File: /var/www/ipsremont-demo/app/Console/Commands/OrdersExportTo1s.php
<?php
namespace App\Console\Commands;
use App\Models\Order;
use App\Models\Region;
use App\Repository\Branch\BranchRepository;
use App\Repository\Order\OrderRepository;
use App\Services\Order\OrderService;
use DOMDocument;
use Exception;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use SimpleXMLElement;
class OrdersExportTo1s extends AbstractImport
{
protected string $channel = 'orders1c';
protected $signature = 'orders1c:integrate {--d|debug} {--e|echo} {--f|force}';
protected string $title = 'Отправляем заявки в 1С';
/**
* @param string $data
*
* @return SimpleXMLElement|false
*/
protected function formatData($data)
{
$data = iconv('Windows-1251', 'UTF-8', $data);
$xml = new SimpleXMLElement($data);
//$data = json_decode($data);
//if (empty($data)) return false;
//if (config('import1c.write_logs')) {
// Log::channel($this->channel)->info($data);
//}
return $xml;
}
protected function sendXML($data, $database = 'RUS'): string
{
$url = config('import1c.url_orders') . "/" . $database;
$this->line(PHP_EOL . '<fg=yellow>Request URL:</> ' . $url . PHP_EOL);
$dom = new DOMDocument();
$dom->encoding = 'utf-8';
$dom->xmlVersion = '1.0';
$dom->formatOutput = true;
$root = $dom->createElement('orders');
foreach ($data as $orderData) {
$orderNode = $dom->createElement('order');
foreach ($orderData as $key => $value) {
if (!is_array($value)) {
$childNode = $dom->createElement($key, $value);
$orderNode->appendChild($childNode);
} else {
$partsNode = $dom->createElement('parts');
foreach ($value as $part) {
$partNode = $dom->createElement('part');
$childNode = $dom->createElement('code', $part['code']);
$partNode->appendChild($childNode);
$childNode = $dom->createElement('quantity', $part['quantity']);
$partNode->appendChild($childNode);
$partsNode->appendChild($partNode);
}
$orderNode->appendChild($partsNode);
}
}
$root->appendChild($orderNode);
}
$dom->appendChild($root);
$body = $dom->saveXML(null, LIBXML_NOEMPTYTAG);
if ($this->isVerbose) {
$this->warn('Данные для 1С:');
print_r($body);
$this->line('');
}
$response = Http::withBasicAuth(config('import1c.username'), config('import1c.password'))->timeout(30)->withBody($body, 'text/xml')->post($url);
if (200 !== $response->status()) {
throw new Exception($response->body());
}
$responseBody = $response->body();
if (config('import1c.write_logs')) {
Log::channel($this->channel)->info($response->body());
}
return $responseBody;
}
public function executeCommand(Region $region)
{
$branchIds = BranchRepository::getBranchIdsByRegion($this->region->id);
if (empty($branchIds)) {
$this->line('Подразделения не найдены');
return;
}
$orders = OrderRepository::getNewOrdersForReceiver($branchIds)->keyBy('id');
$this->line('Найдено заявок: ' . $orders->count());
if ($orders->isEmpty()) {
return;
}
foreach ($orders as $order) {
$this->line('Заявка: ' . $order->id);
}
$data = OrderService::formatOrdersForReceiver($orders);
if (empty($data)) {
$this->warn('Нет данных');
return;
}
try {
$responseData = $this->sendXml($data, $region->external_database_code);
} catch (Exception $exception) {
$this->error($exception->getMessage());
return;
}
$responseData = $this->formatData($responseData);
if (!empty($responseData)) {
foreach ($responseData->order as $item) {
$item->crm_id = trim($item->crm_id);
$item->code = trim($item->code);
$item->result = trim((string) $item->result);
if (false !== strpos($item->result, 'Ошибка')) {
$this->error($item->result);
}
$crmId = (int) $item->crm_id;
if (!isset($orders[$crmId])) {
continue;
}
/** @var Order $order */
$order = $orders[$crmId];
$order->last_1c_date = now();
if ($item->code && $item->result == 'Заявка принята') {
$order->external_id = $item->code;
if ($order->status == Order::STATUS_NEW) {
$order->status = Order::STATUS_AWAITING_CONFIRMATION;
}
$order->errors = 0;
$order->error_text = '';
$order->dispatch = 0;
} else {
$order->error_text = $item->result;
$order->errors = 1;
}
$order->save();
}
}
$ids = $orders->keys();
OrderService::unLockOrders($ids);
}
}