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;
}
}