File: /var/www/ipsremont-demo/app/Console/Commands/ImportAllDetails.php
<?php
namespace App\Console\Commands;
use App\Http\Requests\Part\ImportPartRequest;
use App\Models\Part;
use App\Services\ImportService;
use App\Services\Part\PartService;
use App\Traits\Base1c;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\Console\Command\Command as CommandAlias;
class ImportAllDetails extends Command
{
use Base1c;
private string $method = 'GetAllDetails';
protected $channel = 'importAllDetails';
protected $signature = 'import:all-details {--d|debug} {--e|echo}';
protected $description = 'Import all details from 1c';
public function handle(): int
{
$isDebug = (bool) $this->option('debug');
$this->isVerbose = (bool) $this->option('echo');
$this->info('Импортируем данные по остаткам деталей из 1С ' . date('Y-m-d H:i:s'));
if ($isDebug) {
$data = file_get_contents(storage_path() . '/' . $this->method . '.json');
$data = json_decode($data);
} else {
try {
$url = $this->getRequestUrl();
if ($this->isVerbose) {
$this->warn('Request URL:');
$this->warn($url);
}
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Length: 0'],
CURLOPT_USERPWD => config('import1c.username') . ":" . config('import1c.password'),
]);
$response = iconv('Windows-1251', 'UTF-8', curl_exec($curl));
curl_close($curl);
Log::channel('importAllDetailsResponse')->debug(trim($response));
$decodedResponse = json_decode($response);
if (JSON_ERROR_NONE != json_last_error()) {
$this->error('Ошибка преобразования данных');
return CommandAlias::FAILURE;
}
} catch (Exception $exception) {
$this->error($exception->getMessage());
return CommandAlias::FAILURE;
}
if (!$response) {
$this->warn('Нет ответа от сервера 1С');
return CommandAlias::FAILURE;
}
$data = $decodedResponse;
}
if (!$data) {
$this->info('Новых данных нет');
return CommandAlias::SUCCESS;
}
if ($this->isVerbose) {
$this->line('');
$this->warn('Данные из 1С:');
print_r($data);
$this->line('');
}
$errors = [];
$this->line('Получено деталей: ' . count($data));
foreach ($data as $item) {
if ($this->isVerbose) {
$this->line($item->code . ' ' . $item->name);
}
$this->total++;
$request = new ImportPartRequest();
$price = trim((string) $item->price);
$price = preg_replace('/[^0-9,.]/', '', $price);
$price = str_replace(',', '.', $price);
$price = (float) $price;
$innerData = [
'code' => $item->code,
'name' => $item->name,
'unit' => $item->BaseUnitOfMeasure,
'action' => $item->action,
'storage' => $item->storage ?? [],
'price' => $price,
];
$item->unit = $item->BaseUnitOfMeasure;
$validator = Validator::make($innerData, $request->rules());
if ($validator->fails()) {
$errors[] = $validator->errors();
$item->date = $this->date;
$this->failedItems[] = $item;
} else {
switch ($item->action) {
case ImportService::NEW:
case ImportService::UPDATE:
/** @var Part $part */
$part = Part::query()->where('external_id', $item->code)->first();
if (empty($part)) {
$this->success++;
continue 2;
}
if ($part->price != $innerData['price']) {
$oldPrice = $part->price;
$part->price = $innerData['price'];
$part->save();
$this->line('Обновлена цена у части с ID ' . $part->id . ' с ' . $oldPrice . ' на ' . $part->price);
}
if (isset($item->storage) && $item->storage) {
foreach ($item->storage as $externalId => $amount) {
PartService::fillStorage($part, $externalId, (int) $amount);
}
}
break;
case ImportService::DELETE:
Part::query()->where('external_id', $item->code)->delete();
break;
}
$this->success++;
}
}
if (!empty($errors)) {
$this->error('Ошибки:');
foreach ($errors as $error) {
print_r($error->toArray());
}
}
$this->info('Готово!');
if (!empty($this->failedItems)) {
$this->warn('C ошибками: ' . count($this->failedItems));
}
$this->info('Итого: ' . $this->success . '/' . $this->total);
return CommandAlias::SUCCESS;
}
}