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/ImportAllDetails.php
<?php

namespace App\Console\Commands;

use App\Http\Requests\Part\ImportPartRequest;
use App\Models\Part;
use App\Services\ImportService;
use App\Services\Part\PartService;
use App\Traits\Base1c;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\Console\Command\Command as CommandAlias;

class ImportAllDetails extends Command
{

    use Base1c;

    private string $method = 'GetAllDetails';

    protected $channel = 'importAllDetails';

    protected $signature = 'import:all-details {--d|debug} {--e|echo}';

    protected $description = 'Import all details from 1c';


    public function handle(): int
    {
        $isDebug = (bool) $this->option('debug');
        $this->isVerbose = (bool) $this->option('echo');

        $this->info('Импортируем данные по остаткам деталей из 1С ' . date('Y-m-d H:i:s'));

        if ($isDebug) {
            $data = file_get_contents(storage_path() . '/' . $this->method . '.json');
            $data = json_decode($data);
        } else {
            try {
                $url = $this->getRequestUrl();
                if ($this->isVerbose) {
                    $this->warn('Request URL:');
                    $this->warn($url);
                }
                $curl = curl_init();
                curl_setopt_array($curl, [
                    CURLOPT_URL => $url,
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => '',
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 0,
                    CURLOPT_FOLLOWLOCATION => true,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => 'POST',
                    CURLOPT_HTTPHEADER => ['Content-Length: 0'],
                    CURLOPT_USERPWD => config('import1c.username') . ":" . config('import1c.password'),
                ]);
                $response = iconv('Windows-1251', 'UTF-8', curl_exec($curl));
                curl_close($curl);

                Log::channel('importAllDetailsResponse')->debug(trim($response));

                $decodedResponse = json_decode($response);
                if (JSON_ERROR_NONE != json_last_error()) {
                    $this->error('Ошибка преобразования данных');

                    return CommandAlias::FAILURE;
                }
            } catch (Exception $exception) {
                $this->error($exception->getMessage());

                return CommandAlias::FAILURE;
            }

            if (!$response) {
                $this->warn('Нет ответа от сервера 1С');

                return CommandAlias::FAILURE;
            }

            $data = $decodedResponse;
        }

        if (!$data) {
            $this->info('Новых данных нет');

            return CommandAlias::SUCCESS;
        }

        if ($this->isVerbose) {
            $this->line('');
            $this->warn('Данные из 1С:');
            print_r($data);
            $this->line('');
        }

        $errors = [];
        $this->line('Получено деталей: ' . count($data));
        foreach ($data as $item) {
            if ($this->isVerbose) {
                $this->line($item->code . ' ' . $item->name);
            }
            $this->total++;
            $request = new ImportPartRequest();
            $price = trim((string) $item->price);
            $price = preg_replace('/[^0-9,.]/', '', $price);
            $price = str_replace(',', '.', $price);
            $price = (float) $price;
            $innerData = [
                'code' => $item->code,
                'name' => $item->name,
                'unit' => $item->BaseUnitOfMeasure,
                'action' => $item->action,
                'storage' => $item->storage ?? [],
                'price' => $price,
            ];
            $item->unit = $item->BaseUnitOfMeasure;
            $validator = Validator::make($innerData, $request->rules());

            if ($validator->fails()) {
                $errors[] = $validator->errors();
                $item->date = $this->date;
                $this->failedItems[] = $item;
            } else {
                switch ($item->action) {
                    case ImportService::NEW:
                    case ImportService::UPDATE:
                        /** @var Part $part */
                        $part = Part::query()->where('external_id', $item->code)->first();
                        if (empty($part)) {
                            $this->success++;

                            continue 2;
                        }

                        if ($part->price != $innerData['price']) {
                            $oldPrice = $part->price;
                            $part->price = $innerData['price'];
                            $part->save();

                            $this->line('Обновлена цена у части с ID ' . $part->id . ' с ' . $oldPrice . ' на ' . $part->price);
                        }

                        if (isset($item->storage) && $item->storage) {
                            foreach ($item->storage as $externalId => $amount) {
                                PartService::fillStorage($part, $externalId, (int) $amount);
                            }
                        }
                        break;
                    case ImportService::DELETE:
                        Part::query()->where('external_id', $item->code)->delete();
                        break;
                }
                $this->success++;
            }
        }

        if (!empty($errors)) {
            $this->error('Ошибки:');
            foreach ($errors as $error) {
                print_r($error->toArray());
            }
        }

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

        if (!empty($this->failedItems)) {
            $this->warn('C ошибками: ' . count($this->failedItems));
        }

        $this->info('Итого: ' . $this->success . '/' . $this->total);

        return CommandAlias::SUCCESS;
    }

}