HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/ipsremont-demo/app/Console/Commands/ImportOrders.php
<?php

namespace App\Console\Commands;

use App\Models\Branch;
use App\Models\ImportPackage;
use App\Models\Order;
use App\Models\Region;
use App\Models\Service\Service;
use App\Models\Shipment;
use App\Repository\Shipment\ShipmentRepository;
use App\Services\Order\OrderService;
use Exception;
use SimpleXMLElement;
use Symfony\Component\Console\Command\Command as CommandAlias;

class ImportOrders extends AbstractImport
{

    protected string $fileConfig = 'file_orders';

    protected string $channel = 'importOrders';

    protected string $method = 'GetRequests';

    protected $signature = 'import:orders {--d|debug} {--e|echo} {--f|force}';

    protected $description = 'Import orders from 1c';
    protected string $title = 'Импортируем данные по заявкам из 1С';

    protected function formatData($data, bool $isDebug = false)
    {
        $data = trim($data);
        $data = str_replace('&', '', $data);

        if (empty($data)) {
            return false;
        }

        if (!$isDebug) {
            $data = iconv('Windows-1251', 'UTF-8', $data);
        }

        return new SimpleXMLElement($data);
    }

    private function validateOrder(array $orderData, $order): ?string
    {
        if (!empty($orderData['post_type'])) {
            if (!in_array(mb_strtoupper($orderData['post_type']), Shipment::deliveryService())) {
                $this->failedItems[] = $order;

                return 'Неверный post_type (' . $orderData['post_type'] . ')';
            }
            if (empty($orderData['track_number'])) {
                $this->failedItems[] = $order;

                return 'Неверный track_number';
            }
        }
        if (empty($orderData['type'])) {
            $this->failedItems[] = $order;

            return 'Необходимо указать поле type';
        }
        if (!in_array($orderData['type'], [Order::REPAIR_PAID, Order::REPAIR_WARRANTY])) {
            $this->failedItems[] = $order;

            return 'Неверный type (' . $orderData['type'] . ')';
        }
        if (empty($orderData['service_code'])) {
            $this->failedItems[] = $order;

            return 'Необходимо указать поле service_code';
        } else {
            $service = Service::query()->where('external_id', $orderData['service_code'])->first();
            if (empty($service)) {
                $this->failedItems[] = $order;

                return 'Данный сервис отсутствует в системе (' . $orderData['service_code'] . ')';
            }
        }
        if (empty($orderData['branch_code'])) {
            $this->failedItems[] = $order;

            return 'Необходимо указать поле branch_code';
        } else {
            $branch = Branch::query()->where('external_id', $orderData['branch_code'])->first();
            if (empty($branch)) {
                $this->failedItems[] = $order;

                return 'Данное подразделение отсутствует в системе (' . $orderData['branch_code'] . ')';
            }
        }

        return null;
    }

    private function getData(Region $region)
    {
        if ($this->isDebug) {
            $this->warn('Данные из 1С:');
            $data = $this->loadFromFile();
            $this->line($data);

            return $data;
        }

        try {
            $this->connect(false, $region->external_database_code);
        } 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());

            return CommandAlias::FAILURE;
        }

        $data = $this->response->body();
        if ($this->isVerbose) {
            $this->warn('Данные из 1С:');
            $this->line(iconv('Windows-1251', 'UTF-8', $data));
            if ($this->isDebug) {
                $this->line($data);
            }
            $this->line('');
        }

        return $data;
    }

    public function executeCommand(Region $region)
    {
        if ($this->isForce) {
            $forceCheck = $this->ask('Вы уверены что хотите принять все заявки? [y/N]', 'n');
            $this->isForce = 'y' === strtolower($forceCheck);
        }

        $data = $this->getData($region);
        if (is_numeric($data)) {
            return $data;
        }

        if (!$this->isDebug) {
            $this->logResponse('importOrdersResponse', iconv('Windows-1251', 'UTF-8', $data));
        }
        $xml = $this->formatData($data, $this->isDebug);
        if (!$xml) {
            return CommandAlias::FAILURE;
        }

        $ordersAdded = 0;
        $ordersUpdated = 0;

        $resultArray = [];

        $this->packageNumber = intval(preg_replace('/[^0-9]/', '', trim((string) $xml->PackageNumber)));
        $this->date = date('Y-m-d H:i:s', strtotime($xml->DateOfRequest));
        $this->line('Метод: ' . $this->method);
        $this->line('Номер пакета: ' . $this->packageNumber);

        $importPackage = ImportPackage::getActual($this->method, $this->packageNumber, $region->id);
        if (!empty($importPackage) && empty($xml->orders->order)) {
            $this->info('Данный пакет уже был принят');
            $this->total = 1;
            $this->success = 1;
        } else {
            $errors = [];
            if (!empty($xml->orders->order)) {
                foreach ($xml->orders->order as $order) {
                    $orderData = [
                        'crm_id' => trim((string) $order->crm_id),
                        'code' => trim((string) $order->code),
                        'date' => trim((string) $order->created_at),
                        'created_at' => trim((string) $order->created_at),
                        'action' => trim((string) $order->action),
                        'service_code' => trim((string) $order->service_code),
                        'branch_code' => trim((string) $order->branch_code),
                        'status' => trim((string) $order->status),
                        'created_by_manager' => trim((string) $order->created_by_manager),
                        'type' => trim((string) $order->type),
                        'invoice' => trim((string) $order->invoice),
                        'additional_info' => trim((string) $order->additional_info),
                        'track_number' => trim((string) $order->track_number),
                        'post_type' => ShipmentRepository::getCodeByName(mb_strtoupper(trim((string) $order->post_type))),
                        'parts' => $order->parts,
                    ];

                    $this->total++;
                    if ($this->isForce) {
                        $this->success++;
                        continue;
                    }
                    $result = [];

                    $orderCode = $orderData['code'];
                    $orderErrors = $this->validateOrder($orderData, $order);
                    if (!empty($orderErrors)) {
                        $errors[$orderCode] = $orderErrors;
                        continue;
                    }

                    $d_result = OrderService::import($orderData);
                    $result[] = $d_result;

                    if ($d_result['crm_id']) {
                        $this->success++;
                        if (empty($orderData['crm_id'])) {
                            $ordersAdded++;
                        } else {
                            $ordersUpdated++;
                        }
                    } else {
                        $this->failedItems[] = $order;
                        $error = json_decode($d_result['result']);
                        if (JSON_ERROR_NONE == json_last_error()) {
                            $errors[$orderCode] = json_encode($error, JSON_UNESCAPED_UNICODE);
                        } else {
                            $errors[$orderCode] = $d_result['result'];
                        }
                    }
                    $resultArray[] = $result;
                }
            }

            if ($this->isDebug) {
                return CommandAlias::SUCCESS;
            }

            foreach ($errors as $orderCode => $error) {
                $this->error($orderCode . ': ' . $error);
            }

            if ($this->isForce) {
                $this->total = 1;
                $this->success = 1;
            }
        }

        $this->sendResult();

        $this->info('Готово!');

        if (!empty($ordersAdded)) {
            $this->info('Новых заявок: ' . $ordersAdded);
        }
        if (!empty($ordersUpdated)) {
            $this->info('Заявок обновлено: ' . $ordersUpdated);
        }
        if (!empty($this->failedItems)) {
            $this->warn('Заявок с ошибками: ' . count($this->failedItems));
        }
        $this->info('Итого: ' . $this->total);

        $result = $this->formatResult($resultArray);

        if ($this->isVerbose) {
            $this->line('');
            $this->warn('Результат:');
            $result = json_encode(json_decode($result), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
            if (empty($result)) {
                $this->warn('Нет данных');
            } else {
                print_r($result);
            }
            $this->line('');
        }

        return CommandAlias::SUCCESS;
    }

}