File "IntegrationRepository-20260128120809.php"

Full Path: /var/www/html/back/app/Repositories/Integrations/IntegrationRepository-20260128120809.php
File size: 11.17 KB
MIME-type: text/x-php
Charset: utf-8

<?php

namespace App\Repositories\Integrations;


use App\Domain\Payment\Enums\PaymentStatusEnum;
use App\Domain\Payment\Enums\PaymentTypeEnum;
use App\Domain\Payment\PaymentLogService;
use App\DTO\IntegrationPaymentDTO;
use App\Models\Account;
use App\Models\Counterparty;
use App\Models\Organization;
use App\Models\Payment;
use App\Repositories\Integrations\Interfaces\IntegrationInterface;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class IntegrationRepository implements IntegrationInterface
{

    protected PaymentLogService $paymentLogService;

    public function __construct()
    {
        $this->paymentLogService = app()->make(PaymentLogService::class);
    }

    public function createDataInAccountDb($modelId, $account)
    {
        $searchAccount = null;

        $organization = Organization::query()->where(['model_id' => $modelId, 'external_id' => $account['organization_id']])->first();

        $searchAccount = Account::query()->where([
            'model_id' => $modelId,
            'external_id' => trim($account['id'])
        ])->first();

        if (!$searchAccount) {
            $searchAccount = Account::query()->where([
                'model_id' => $modelId,
                'number' => trim($account['number'])
            ])->first();
        }

        if ($searchAccount) {
            $searchAccount->update(['external_id' => $account['id'],
                'deposit' => $account['deposit'],
                'bank_name' => $account['bank_name'],
                'bank_bic' => $account['bank_bic'],
                'bank_city' => $account['bank_city'],
//                'balance_of_the_date' => $account['balance_of_the_date'],
                'cor_number' => $account['cor_number'],
                'name' => $account['name'],
                'added' => $account['added'],
                'archived' => $account['archived'],
                'current_balance' => $account['deposit'],
            ]);
            return $searchAccount;
        } else {
            return Account::query()->create([
                'external_id' => $account['id'],
                'organization_id' => $organization->id,
                'model_id' => $modelId,
                'name' => $account['name'],
                'archived' => $account['archived'],
                'added' => $account['added'],
                'balance_of_the_date' => $account['balance_of_the_date'],
                'bank_name' => $account['bank_name'],
                'bank_bic' => $account['bank_bic'],
                'cor_number' => $account['cor_number'],
                'number' => $account['number'],
                'bank_city' => $account['bank_city'],
                'deposit' => $account['deposit']
            ]);
        }
    }

    public function createDataInCounterpartyDb($modelId, $counterparty)
    {
        $searchCounterparty = null;

        $searchCounterparty = Counterparty::query()->where([
            'model_id' => $modelId,
            'external_id' => trim($counterparty['id'])
        ])->first();

        if (!$searchCounterparty) {
            $searchCounterparty = Counterparty::query()->where([
                'model_id' => $modelId,
                'inn' => trim($counterparty['inn'])
            ])->first();
        }

        if ($searchCounterparty) {
            $searchCounterparty->update(['external_id' => $counterparty['id'],
                'name' => $counterparty['name'],
                'comment' => $counterparty['comment'],
                'kpp' => $counterparty['kpp'],
                'archived' => $counterparty['archived'],
            ]);
            return $searchCounterparty;
        } else {
            return Counterparty::query()->create([
                'external_id' => $counterparty['id'],
                'model_id' => $modelId,
                'name' => $counterparty['name'],
                'archived' => $counterparty['archived'],
                'inn' => $counterparty['inn'],
                'kpp' => $counterparty['kpp'],
                'comment' => $counterparty['comment'],
            ]);
        }
    }

    public function createDataInOrganizationsDb($modelId, $organization)
    {
        $searchOrganization = null;

        $searchOrganization = Organization::query()->where([
            'model_id' => $modelId,
            'external_id' => trim($organization['id'])
        ])->first();

        if (!$searchOrganization) {
            $searchOrganization = Organization::query()->where([
                'model_id' => $modelId,
                'inn' => trim($organization['inn'])
            ])->first();
        }

        if ($searchOrganization) {
            $searchOrganization->update(['external_id' => $organization['id'],
                'full_name' => $organization['fname'],
                'short_name' => $organization['name'],
                'kpp' => $organization['kpp'],
                'archived' => $organization['archived'],
            ]);
            return $searchOrganization;
        } else {
            return Organization::query()->create([
                'model_id' => $modelId,
                'external_id' => $organization['id'],
                'full_name' => $organization['fname'],
                'short_name' => $organization['name'],
                'inn' => $organization['inn'],
                'kpp' => $organization['kpp'],
                'archived' => $organization['archived'],
            ]);
        }
    }

    public function createDataInPaymentsDb($modelId, $payment)
    {
        return DB::transaction(function () use ($modelId, $payment) {

            $paymentModel = null;

            if (is_numeric($payment['id'])) {
                $paymentModel = Payment::query()->find((int)$payment['id']);
            }

            if (is_string($payment['id'])) {
                if (ctype_digit($payment['id'])) {
                    $paymentModel = Payment::query()
                        ->where('external_id', $payment['id'])
                        ->orWhere('id', (int)$payment['id'])
                        ->first();
                } else {
                    $paymentModel = Payment::query()
                        ->where('external_id', $payment['id'])
                        ->first();
                }
            }

            if ($paymentModel) {
                $original = $paymentModel->getOriginal();

                $account = Account::query()->find($paymentModel->account_id);

                $importAccount = Account::query()
                    ->where([
                        'model_id' => $modelId,
                        'external_id' => $payment['account_id']
                    ])
                    ->first();

                $status = match ($paymentModel->payment_type) {
                    PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value => PaymentStatusEnum::STATUS_RECEIVED->value,
                    PaymentTypeEnum::PAYMENT_TYPE_MOVING->value => PaymentStatusEnum::STATUS_MOVING->value,
                    PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value => PaymentStatusEnum::STATUS_ISSUED->value,
                    PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value => PaymentStatusEnum::STATUS_PAID->value,
                    default => PaymentStatusEnum::STATUS_SENT->value,
                };

                if ((!isset($account)) || (($account->number != $importAccount->number) && ($account->external_id != $importAccount->external_id))) {
                    $paymentModel->update(['account_id' => $importAccount->id]);
                }


                $paymentModel->update([
                    'status' => $status,
                    'amount' => $payment['amount'],
                    'payment_date' => $payment['date'],
                    'actual_date' => $payment['payment_date'],
                    'purpose_of_payment_1c' => $payment['appointment'] ?? 'Платеж из 1с',
                    'note_1c' => $payment['comment'] ?? '',
                    'account_debit_1c' => $importAccount->name ?? $account?->name ?? null,
                ]);

                $distribution = $paymentModel->distributions()->first();
                if ($distribution) {
                    $distribution->update(['amount' => $payment['amount']]);
                }

                $this->createLogPayment($paymentModel, $original);
            } else {
                $paymentDTO = IntegrationPaymentDTO::fromArray($modelId, $payment);
                $account = $this->getAccountId($modelId, $payment['account_id']);
                $counterpartyId = $this->getCounterpartyId($modelId, $payment['counterparty_id']);
                $organizationId = $this->getOrganizationId($modelId, $payment['organization_id']);
                $paymentData = $paymentDTO->toArray($account, $counterpartyId, $organizationId);

                $paymentModel = Payment::query()->create($paymentData);

                //КОСТЫЛЬ ))Привет разрабу, который это разгребает, это было сделано до меня
                $paymentModel->distributions()->create([
                    'amount' => 0.00,
                    'amount_limit' => 0.00,
                ]);

                $this->createLogPayment($paymentModel, null);
            }
            return $paymentModel;
        });
    }


    public function createLogPayment($payment, $original)
    {
        if (!$original) {
            $original = $payment->getOriginal();
        }

        $changes = [];
        foreach ($payment->getAttributes() as $field => $newValue) {
            $oldValue = $original[$field] ?? null;
            if (($field == 'status') || ($field == 'amount') || ($field == 'name') || ($field == 'payment_date') || ($field == 'account_id')) {
                if ($field == 'payment_date') {
                    $oldValue = Carbon::parse($oldValue)->toDateString();
                    $newValue = Carbon::parse($newValue)->toDateString();
                }
                if ($oldValue != $newValue) {
                    if ($field == 'account_id') {
                        if($oldValue != null) {
                            $oldValue = Account::query()->find($oldValue)->name;
                        }
                        $newValue = Account::query()->find($newValue)->name;
                    }

                    $changes[$field] = [(string)$oldValue ?? null, (string)$newValue];
                }
            }
        }

        if (!empty($changes)) {
            $this->paymentLogService->store(
                1,
                $payment,
                $original['status'] instanceof PaymentStatusEnum ? $original['status']->value : $payment['status'],
                null,
                '',
                $changes
            );
        }
    }

    public function getOrganizationId($modelId, $organizationExternalId)
    {
        return Organization::query()->where(['model_id' => $modelId, 'external_id' => $organizationExternalId])->first()?->id;
    }

    public function getCounterpartyId($modelId, $counterpartyExternalId)
    {
        return Counterparty::query()->where(['model_id' => $modelId, 'external_id' => $counterpartyExternalId])->first()?->id;
    }

    public function getAccountId($modelId, $accountExternalId)
    {
        return Account::query()->where(['model_id' => $modelId, 'external_id' => $accountExternalId])->first();
    }
}