File: /var/www/ipsremont-demo/app/Traits/Base1c.php
<?php
namespace App\Traits;
use App\Models\ImportPackage;
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
trait Base1c
{
public bool $isVerbose = false;
public bool $isWeb = false;
public ?Response $response = null;
protected int $packageNumber;
protected string $date = '';
protected int $success = 0;
protected int $total = 0;
protected array $failedItems = [];
protected function getRequestUrl(string $database = ''): string
{
return config('import1c.base_request') . $this->method . '/' . $database;
}
protected function getAnswerUrl($result)
{
$result = rawurlencode($result);
return config('import1c.base_answer') . $result . '/' . $this->packageNumber . '/' . $this->method;
}
/**
* Don't truncate production tables
*
* @return bool
*/
public function canTruncate(): bool
{
return env('APP_ENV') !== 'production';
}
public function logResponse(string $channel, $body)
{
$jsonError = true;
$decodedResponse = [];
if (is_string($body)) {
$decodedResponse = json_decode($body);
$jsonError = JSON_ERROR_NONE == json_last_error();
$decodedResponse = $this->method . PHP_EOL . json_encode($decodedResponse, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
if ($this->response->successful()) {
Log::channel($channel)->debug($jsonError ? $decodedResponse : $body);
} else {
Log::channel($channel)->error($jsonError ? $decodedResponse : $body);
}
}
/** @TODO check the response */
protected function connect(bool $isInit = false, string $database = 'RUS')
{
$response = Http::withBasicAuth(config('import1c.username'), config('import1c.password'))->withOptions(['verify' => false]);
switch ($this->method) {
case 'GetParts':
$url = config('import1c.url_parts') . ($isInit ? '2/' : '') . '/' . $database;
$method = 'get';
break;
// case 'GetApparatus':
// $url = config('import1c.url_devices') . ($isInit ? '2/' : '');
// break;
default:
$url = $this->getRequestUrl($database);
break;
}
$this->line('<fg=yellow>Request URL:</> ' . $url . PHP_EOL);
if ($method ?? 'post' === 'get') {
$response = $response->get($url);
} else {
$response = $response->post($url);
}
$this->response = $response;
$body = $response->body();
switch ($this->method) {
case 'GetRequests':
case 'GetDetails':
case 'GetAllDetails':
break;
default:
$this->logResponse('requestResponse', $body);
break;
}
// if (config('import1c.write_logs')) {
// Log::channel('import1s')->info($response->body());
// }
}
private function sendNothing()
{
$result = 'Nothing loaded';
$data = [
[
'НомерПакета' => $this->packageNumber,
'ИмяМетода' => $this->method,
'Имя Параметра' => $result,
'КодУзла' => '112',
],
];
if ($this->isVerbose) {
$this->line('');
$this->warn('Запрос об частичном принятии данных:');
$this->line(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$this->line('');
}
$response = Http::withBasicAuth(config('import1c.username'), config('import1c.password'))->withBody(json_encode($data), 'text/json')->post($this->getAnswerUrl($result));
$responseBody = $response->body();
return json_decode($responseBody);
}
private function sendPartly($errors)
{
$result = 'Partially loaded';
// Build body
$body = [];
foreach ($errors as $item) {
$action = trim((string) $item->action);
$code = trim((string) $item->code);
$date = date('Y-m-d\TH:i:s', strtotime($item->date));
$importDate = date('Y-m-d\TH:i:s', strtotime($this->date));
$bodyItem = [
'СтатусыВыгрузки' => $action,
'НомерПакета' => $this->packageNumber ?? 0,
'Код' => $code,
'Дата' => $date,
'ИДУзла' => '112',
'ДатаОбмена' => $importDate,
];
if (!empty($item->name)) {
$bodyItem['ОбъектОбмена'] = (string) $item->name;
} else {
$bodyItem['ОбъектОбмена'] = 'Заявка на ТМЦ ' . trim($item->code) . ' от ' . date('Y-m-d H:i:s', strtotime($item->date));
}
$body[] = $bodyItem;
}
if ($this->isVerbose) {
$this->line('');
$this->warn('Запрос об частичном принятии данных:');
$this->line(json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$this->line('');
}
$response = Http::withBasicAuth(config('import1c.username'), config('import1c.password'))->withBody(json_encode($body), 'text/json')->post($this->getAnswerUrl($result));
$responseBody = $response->body();
return json_decode($responseBody);
}
private function sendSuccess()
{
$result = 'All loaded';
$data = [
[
'НомерПакета' => $this->packageNumber,
'ИмяМетода' => $this->method,
'Имя Параметра' => $result,
'КодУзла' => '112',
],
];
$response = Http::withBasicAuth(config('import1c.username'), config('import1c.password'))->withBody(json_encode($data), 'text/json')->post($this->getAnswerUrl($result));
$responseBody = $response->body();
$responseBody = iconv('Windows-1251', 'UTF-8', $responseBody);
return json_decode($responseBody);
}
protected function sendData($data)
{
$data = json_encode($data);
$response = Http::post($this->getUrl(), ['data' => $data]);
if (config('import1c.write_logs')) {
$body = $response->body();
$decodedResponse = json_decode($body);
if (JSON_ERROR_NONE == json_last_error()) {
Log::channel($this->channel)->info($decodedResponse);
} else {
Log::channel($this->channel)->info($body);
}
}
}
public function loadFromFile()
{
$path = storage_path() . config('import1c.' . $this->fileConfig);
if (!file_exists($path)) {
return '';
}
$data = file_get_contents($path);
return $data;
}
/**
* Format to json
*
* @param $result
*
* @return false|string
*/
public function formatResult($result)
{
$result = json_encode($result, JSON_UNESCAPED_UNICODE);
if (config('import1c.write_logs')) {
Log::channel($this->channel)->info($result);
}
return $result;
}
public function sendResult()
{
// Задержка на всякий случай, запрос со стороны 1С
usleep(500);
if ($this->isVerbose) {
$this->line('');
$this->warn('Запрос в 1С о результатах импорта:');
}
if ($this->total) {
switch ($this->success) {
case $this->total:
$type = 'Success';
if ($this->isVerbose) {
$this->info($type);
}
$response = $this->sendSuccess();
break;
case 0:
$type = 'Nothing';
if ($this->isVerbose) {
$this->error($type);
}
$response = $this->sendNothing();
break;
default:
$type = 'Partly';
if ($this->isVerbose) {
$this->warn($type);
}
$response = $this->sendPartly($this->failedItems);
break;
}
if ('Nothing' !== $type) {
ImportPackage::create($this->method, $this->packageNumber, $type, $this->region->id ?? null);
}
if (!$this->isWeb) {
$this->line('');
}
if (!$this->isWeb) {
if (!empty($response->SereveAnswers) && false !== strpos((string) $response->SereveAnswers, 'success')) {
$this->info('Сообщение о получении отправлено');
} else {
$this->warn('Не корректный ответ');
}
}
if ($this->isVerbose) {
$this->line('');
$this->warn('Ответ из 1С:');
if (empty($response)) {
$this->error('Пустой ответ');
} else {
$this->line(json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
$this->line('');
}
} elseif ($this->isVerbose) {
$this->line('Данных не было получено');
}
}
protected function formatJsonData($data)
{
$data = trim($data);
$data = iconv('Windows-1251', 'UTF-8', $data);
return json_decode($data);
}
}