File: /var/www/ipsremont-demo/app/Console/Commands/ImportDevices.php
<?php
namespace App\Console\Commands;
use App\Models\SchemaParts;
use App\Services\Device\DeviceService;
use App\Services\Part\PartService;
use App\Services\Schema\SchemaService;
use App\Traits\Base1c;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use SimpleXMLElement;
use Symfony\Component\Console\Command\Command as CommandAlias;
class ImportDevices extends Command
{
use Base1c;
protected string $fileConfig = 'file_devices';
protected string $channel = 'importDevices';
private string $method = 'GetApparatus';
/**
* Load devices from 1c
*
* --mode=file to load data from file
*
* @var string
*/
protected $signature = 'import:devices {--mode=} {--e|echo}';
protected $description = 'Import devices from 1c';
protected function formatData($data)
{
$data = trim($data);
$data = str_replace('&', '', $data);
if ($this->option('mode') != 'file') {
$data = iconv('Windows-1251', 'UTF-8', $data);
}
if (empty($data)) {
return false;
}
return new SimpleXMLElement($data);
}
public function handle(): int
{
$this->isVerbose = (bool) $this->option('echo');
$isFileMode = 'file' === $this->option('mode');
$this->info('Импортируем данные по аппаратам из 1С ' . date('Y-m-d H:i:s'));
if ($isFileMode) {
$data = $this->loadFromFile();
} else {
try {
$this->connect();
} catch (Exception $exception) {
$this->error($exception->getMessage());
return CommandAlias::FAILURE;
}
if (!$this->response) {
$this->warn('Нет ответа от сервера 1С');
return CommandAlias::FAILURE;
}
if ($this->response->status() !== 200) {
$this->warn('Статус ответа ' . $this->response->status());
$this->error('Ошибка: ' . $this->response->body());
return CommandAlias::FAILURE;
}
$data = $this->response->body();
}
if ($this->isVerbose) {
$this->line('');
$this->warn('Данные из 1С:');
print_r($data);
$this->line('');
}
if (!$isFileMode) {
$this->logResponse('importDevicesResponse', iconv('Windows-1251', 'UTF-8', $data));
}
try {
$xml = $this->formatData($data);
if (!$xml) {
return CommandAlias::FAILURE;
}
} catch (Exception $exception) {
$this->error($exception->getMessage());
return CommandAlias::FAILURE;
}
$deviceAdded = 0;
$schemaAdded = 0;
$resultArray = [];
$this->packageNumber = intval(preg_replace('/[^0-9]/', '', trim((string) $xml->PackageNumber)));
$this->date = date('Y-m-d H:i:s', strtotime($xml->DateRequest));
$this->line('Method: ' . $this->method);
$this->line('Package number: ' . $this->packageNumber);
$errors = [];
foreach ($xml->apparatus->apparat as $device) {
$this->info('Аппарат: ' . trim($device->code));
$this->total++;
$deviceAdded++;
$result = [];
$deviceCode = trim((string) $device->code);
$deviceResult = DeviceService::import($device);
$result[] = $deviceResult;
if ($deviceResult['device_id']) {
$this->success++;
$i = 1;
foreach ($device->shemes->sheme as $scheme) {
$schemeCode = trim((string) $scheme->code);
$this->info(' Схема: ' . $schemeCode);
$schemaAdded++;
$schemeResult = SchemaService::import($scheme, $i++, $deviceResult['device_id']);
$result[] = $schemeResult;
if ($schemeResult['schema_external_id']) {
DB::beginTransaction();
SchemaParts::query()->where('schema_external_id', $schemeResult['schema_external_id'])->delete();
foreach ($scheme->accessories->component as $accessory) {
$price = trim((string) $accessory->price);
$price = preg_replace('/[^0-9,.]/', '', $price);
$price = str_replace(',', '.', $price);
$price = (float) $price;
$partData = (object) [
'code' => trim((string) $accessory->code),
'name' => trim((string) $accessory->name),
'unit' => trim((string) $accessory->BaseUnitOfMeasure),
'price' => $price,
'foto' => '',
];
PartService::saveFromImport($partData);
$partCode = trim((string) $accessory->code);
$this->info(' Компонент: ' . $partCode);
$partResult = PartService::import($accessory, $schemeResult['schema_external_id']);
if ($partResult['result'] !== 1) {
$error = json_decode($partResult['result']);
if (JSON_ERROR_NONE == json_last_error()) {
$errors[$partCode] = json_encode($error, JSON_UNESCAPED_UNICODE);
} else {
$errors[$partCode] = $partResult['result'];
}
$this->success--;
DB::rollBack();
}
$result[] = $partResult;
}
DB::commit();
} else {
$errors[$schemeCode] = $schemeResult['result'];
}
}
} else {
$this->failedItems[] = $device;
$errors[$deviceCode] = $deviceResult['result'];
}
$resultArray[] = $result;
}
if (!empty($errors)) {
$this->error('Ошибки:');
foreach ($errors as $code => $error) {
$this->error($code . ': ' . $error);
}
}
$this->sendResult();
$this->info('Готово!');
if (!empty($deviceAdded)) {
$this->info('Аппаратов добавлено: ' . $deviceAdded);
}
if (!empty($schemaAdded)) {
$this->info('Схем добавлено: ' . $schemaAdded);
}
if (!empty($this->failedItems)) {
$this->warn('C ошибками: ' . count($this->failedItems));
}
$this->info('Итого: ' . $this->success . '/' . $this->total);
$this->formatResult($resultArray);
return CommandAlias::SUCCESS;
}
}