/
var
/
www
/
html
/
back
/
app
/
Services
/
Upload File
HOME
<?php declare(strict_types=1); namespace App\Services; use App\Domain\Article\Enums\ArticleTypeEnum; use App\Domain\Payment\Enums\PaymentStatusEnum; use App\Domain\Payment\Enums\PaymentTypeEnum; use App\Exports\PaymentsExport; use App\Http\Resources\CashFlowCreditResource; use App\Http\Resources\CashFlowDebitResource; use App\Http\Resources\CashFlowProjectCreditResource; use App\Http\Resources\ShowUndistributedPaymentsByCounterpartyResource; use App\Models\Article; use App\Models\ArticleGroup; use App\Models\Counterparty; use App\Models\Payment; use App\Models\PaymentDistribution; use App\Repositories\CashFlowIndex\Interfaces\PaymentDistributionsRepositoryInterface; use App\Repositories\CashFlowIndex\Interfaces\TotalAmountRepositoryInterface; use App\Responses\ResponseDto; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Maatwebsite\Excel\Facades\Excel; class CashFlowService { private $distributionsRepository; private $paymentRepository; public function __construct(PaymentDistributionsRepositoryInterface $paymentDistributionsRepository, TotalAmountRepositoryInterface $paymentRepository) { $this->distributionsRepository = $paymentDistributionsRepository; $this->paymentRepository = $paymentRepository; } public function getIncomeAndExpensesShow($modelId, $type, $filters) { $query = PaymentDistribution::query(); $filters = array_filter($filters, function ($value) { return $value !== null; }); $query->where('cashbox', null); if (!empty($filters)) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to']; $query->whereHas('payment', function ($paymentFilterQuery) use ($dateFrom, $dateTo) { $paymentFilterQuery->whereBetween('payment_date', [$dateFrom, $dateTo]); }); } if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } $query->whereHas('payment', function ($paymentFilterQuery) use ($filters) { if (!empty($filters['accounts'])) { $paymentFilterQuery->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $paymentFilterQuery->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $paymentFilterQuery->whereIn('payment_type', $filters['cash']); } $paymentFilterQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value); }); } $query->with(['payment' => function ($paymentQuery) use ($filters) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to']; $paymentQuery->whereBetween('payment_date', [$dateFrom, $dateTo]); } if (!empty($filters['accounts'])) { $paymentQuery->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $paymentQuery->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $paymentQuery->whereIn('payment_type', $filters['cash']); } $paymentQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) ->with('contragent'); }]); switch ($type) { case 'credit': $query->with(['article' => function ($query) use ($modelId) { $query->where('id', '!=', 1) ->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value, 'model_id' => $modelId ]); }])->whereHas('article', function ($query) use ($modelId) { $query->where('id', '!=', 1) ->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value, 'model_id' => $modelId ]); }); break; case 'debit': $query->with(['article' => function ($query) use ($modelId) { $query->where('id', '!=', 1) ->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value, 'model_id' => $modelId ]); }])->whereHas('article', function ($query) use ($modelId) { $query->where('id', '!=', 1) ->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value, 'model_id' => $modelId ]); }); break; default: break; } return $query->get(); } public function getCashIncomeShow($modelId) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId) { $query ->where('model_id', $modelId) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, ]); }) ->with([ 'payment.contragent', 'article', ]); $collection = $query->get(); $collection->each(function ($distribution) { if ( in_array( $distribution->payment->payment_type, [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, ], true ) ) { $distribution->amount = $distribution->cashbox ?? $distribution->amount; } }); return $collection; } public function getReceptionIncomeShow($modelId, $statuses) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId, $statuses) { $query ->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value); if (!empty($statuses)) { $query->whereIn('status', $statuses); } }) ->with([ 'payment.contragent', 'article', ]); $collection = $query->get(); $collection->each(function ($distribution) { $distribution->amount = $distribution->cashbox ?? $distribution->amount; }); return $collection; } public function getUndistributedIncomeShow($modelId, $paymentsMade) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId, $paymentsMade) { $query ->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value) ->whereNull('article_id'); if (!empty($paymentsMade)) { $query->whereIn('status', $paymentsMade); } }) ->with([ 'payment.contragent', 'article', ]); $collection = $query->get(); return $collection; } public function getIssueanceShow($modelId) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId) { $query ->where('model_id', $modelId) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value, PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, ]); }) ->with([ 'payment.contragent', 'article', ]); $collection = $query->get(); $collection->each(function ($distribution) { if ( in_array( $distribution->payment->payment_type, [ PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value, PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, ], true ) ) { $distribution->amount = $distribution->cashbox ?? $distribution->amount; } }); return $collection; } public function getTotalCash($filters, $modelId) { $query = PaymentDistribution::query(); if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } $query->whereHas('payment', function ($paymentQuery) use ($filters, $modelId) { $paymentQuery->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->where('model_id', $modelId); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now()->toDateString(); $paymentQuery->whereBetween('payment_date', [$dateFrom, $dateTo]); } if (!empty($filters['accounts'])) { $paymentQuery->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $paymentQuery->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $paymentQuery->whereIn('payment_type', $filters['cash']); } }); $query->with(['payment' => function ($q) use ($modelId) { $q->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value); }]); $distributions = $query->get(); $totalCash = $distributions->sum(function ($distribution) use ($modelId) { return (float)($distribution->amount ?? 0); }); $totalCash += $this->getTotalCashFromMoving($filters, $modelId); return $totalCash; } public function getTotalCashFromMoving($filters, $modelId) { $query = PaymentDistribution::query(); $query->whereNotNull('cashbox'); $query->whereHas('payment', function ($paymentQuery) use ($modelId, $filters) { $paymentQuery->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereNotNull('actual_date'); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = $filters['date_to'] ?? Carbon::now()->toDateString(); $paymentQuery->whereBetween('actual_date', [$dateFrom, $dateTo]); } if (!empty($filters['accounts'])) { $paymentQuery->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $paymentQuery->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $paymentQuery->whereIn('payment_type', $filters['cash']); } }); if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } $query->with(['payment' => function ($q) use ($modelId) { $q->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereNotNull('actual_date'); }]); $distributions = $query->get(); return $distributions->sum(function ($distribution) { return (float)($distribution->cashbox ?? 0); }); } public function getOtherDataShow($modelId, $type, $filters) { $baseQuery = function ($query) { $query->with('contragent'); }; $query = PaymentDistribution::query(); $query->whereHas('payment', function ($query) use ($modelId) { $query->where('model_id', $modelId); }); switch ($type) { case 'moving': $query->with(['payment' => function ($query) use ($baseQuery, $modelId, $filters) { $query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId]); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }]) ->whereHas('payment', function ($query) use ($baseQuery, $modelId, $filters) { $query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId]); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }); break; case 'commission': $query->where('comission', '!=', null) ->with(['payment' => function ($query) use ($baseQuery, $modelId, $filters) { $query->where('model_id', $modelId); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qMoving) use ($dateFrom, $dateTo) { $qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); })->orWhere(function ($qOther) use ($dateFrom, $dateTo) { $qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }]) ->whereHas('payment', function ($query) use ($baseQuery, $modelId, $filters) { $query->where('model_id', $modelId); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qMoving) use ($dateFrom, $dateTo) { $qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); })->orWhere(function ($qOther) use ($dateFrom, $dateTo) { $qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }); break; case 'cash': $query->where('cashbox', '!=', null) ->with(['payment' => function ($query) use ($baseQuery, $modelId, $filters) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }])->whereHas('payment', function ($query) use ($baseQuery, $modelId, $filters) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }); break; case 'cash-credit': $query->with(['payment' => function ($query) use ($baseQuery, $modelId, $filters) { $query->where(function ($q) use ($modelId, $filters) { $q->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, 'model_id' => $modelId]) ->orWhere(function ($q2) use ($modelId) { $q2->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId, 'status' => PaymentStatusEnum::STATUS_RECEIVED->value]) ->whereNotNull('actual_date'); }); }); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }]) ->whereHas('payment', function ($query) use ($baseQuery, $modelId, $filters) { $query->where(function ($q) use ($modelId) { $q->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, 'model_id' => $modelId]) ->orWhere(function ($q2) use ($modelId) { $q2->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId, 'status' => PaymentStatusEnum::STATUS_RECEIVED->value]) ->whereNotNull('actual_date'); }); }); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); $query->where(function ($q) use ($dateFrom, $dateTo) { $q->where(function ($qActual) use ($dateFrom, $dateTo) { $qActual->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); })->orWhere(function ($qPayment) use ($dateFrom, $dateTo) { $qPayment->whereNull('actual_date') ->whereBetween('payment_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereHas('distributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); })->with(['distributions' => function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } $baseQuery($query); }); break; default: break; } if (!empty($filters['accounts'])) { $query->whereHas('payment', function ($query) use ($filters) { $query->whereIn('account_id', $filters['accounts']); }); } return $query->get(); } public function getActivePageProjectToIndex(int $modelID, $filters) { $paymentDistributionsCredit = $this->distributionsRepository->getPaymentDistributionsProject($modelID, $filters, ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value); $paymentDistributionsDebit = $this->distributionsRepository->getPaymentDistributionsProject($modelID, $filters, ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value); $totalAmountCreditPayment = $this->paymentRepository->getTotalAmountPayment($modelID, $filters, $credit = true); $totalAmountDebitPayment = $this->paymentRepository->getTotalAmountPayment($modelID, $filters, $credit = false); $totalCredit = $this->sumTotalAmount($paymentDistributionsCredit); $totalDebit = $this->sumTotalAmount($paymentDistributionsDebit); $formattedToProjectCredit = $this->sortToProject($paymentDistributionsCredit, $credit = true); $formattedToProjectDebit = $this->sortToProject($paymentDistributionsDebit, $credit = false); $totalAmountDebitCashPayment = $this->paymentRepository->getTotalAmountCashPayment($modelID, $filters, $credit = false, $debitType = 'cash'); $totalAmountCashDebitCommissionPayment = $this->paymentRepository->getTotalCommissionPaymentDistribution($modelID, $filters, $debitType); $totalMoving = $this->paymentRepository->getTotalAmountCashPayment($modelID, $filters, $credit = false, $debitType = 'moving'); $totalCash = $this->getTotalCash($filters, $modelID); return new ResponseDto( data: [ 'credit' => [ 'static' => [ 'total_amount' => $totalCredit + $totalAmountCreditPayment, 'articles' => CashFlowCreditResource::collection($paymentDistributionsCredit), 'not_distribution_payments_total_amount' => $totalAmountCreditPayment, 'other_data' => [ 'total_cash' => $totalCash, ], ], 'dynamic' => [ 'projects' => $formattedToProjectCredit, ], ], 'debit' => [ 'static' => [ 'total_amount' => $totalDebit + $totalAmountDebitPayment, 'articles' => CashFlowDebitResource::collection($paymentDistributionsDebit), 'not_distribution_payments_total_amount' => $totalAmountDebitPayment, 'other_data' => [ 'moving' => $totalMoving, 'commission' => $totalAmountCashDebitCommissionPayment, 'cash' => $totalAmountDebitCashPayment, ], ], 'dynamic' => [ 'projects' => $formattedToProjectDebit, ], ], ], status: true ); } public function getShowArticlesGroup($modelId, $articleGroupId, $filters) { $query = ArticleGroup::query() ->where('model_id', $modelId) ->where('id', $articleGroupId); $articlesCallback = function ($query) use ($filters) { $query->has('paymentDistributions')->with([ 'paymentDistributions' => function ($query) use ($filters) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to']; $query->whereHas('payment', function ($q) use ($filters, $dateFrom, $dateTo) { $q->whereBetween('payment_date', [$dateFrom, $dateTo]); }); } if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } if (!empty($filters['accounts'])) { $query->whereHas('payment', function ($q) use ($filters) { $q->whereIn('account_id', $filters['accounts']); }); } if (!empty($filters['payments_made'])) { $query->whereHas('payment', function ($q) use ($filters) { $q->whereIn('status', $filters['payments_made']); }); } if (!empty($filters['cash'])) { $query->whereHas('payment', function ($q) use ($filters) { $q->whereIn('payment_type', $filters['cash']); }); } }, 'paymentDistributions.payment' => function ($query) use ($filters) { if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } }, 'paymentDistributions.project', ]); if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to']; $query->whereHas('paymentDistributions.payment', function ($q) use ($filters, $dateFrom, $dateTo) { $q->whereBetween('payment_date', [$dateFrom, $dateTo]); }); } if (!empty($filters['projects'])) { $query->whereHas('paymentDistributions', function ($q) use ($filters) { $q->whereIn('project_id', $filters['projects']); }); } if (!empty($filters['accounts'])) { $query->whereHas('paymentDistributions.payment', function ($q) use ($filters) { $q->whereIn('account_id', $filters['accounts']); }); } if (!empty($filters['payments_made'])) { $query->whereHas('paymentDistributions.payment', function ($q) use ($filters) { $q->whereIn('status', $filters['payments_made']); }); } if (!empty($filters['cash'])) { $query->whereHas('paymentDistributions.payment', function ($q) use ($filters) { $q->whereIn('payment_type', $filters['cash']); }); } }; $query->with(['articles' => $articlesCallback]); $counterpartyIds = collect(); $paymentsIds = collect(); $articleGroups = $query->first(); $articleGroups->articles->each(function ($article) use (&$counterpartyIds, &$paymentsIds) { $uniqueCounterparties = $article->paymentDistributions ->pluck('payment.contragent') ->unique('id') ->values(); $counterpartyIds = $counterpartyIds->concat($uniqueCounterparties->pluck('id')); $paymentsIds = $paymentsIds->concat($article->paymentDistributions->pluck('payment_id')); }); $counterparties = Counterparty::query() ->whereIn('id', $counterpartyIds) ->with(['payments' => function ($query) use ($paymentsIds) { $query->whereIn('id', $paymentsIds) ->with('distributions.project'); }]) ->get(); $articleGroups->setRelation('counterparties', $counterparties); return $articleGroups; } public function sortToProject($paymentDistributionsCredit, $type) { if ($type) { return CashFlowProjectCreditResource::collection($paymentDistributionsCredit); } else { return CashFlowProjectCreditResource::collection($paymentDistributionsCredit); } } public function getArticleShow($modelId, $articleId, $filters) { $query = Article::query() ->where('model_id', $modelId) ->where('id', $articleId); $applyPaymentFilters = function ($query) use ($filters) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to']; $query->whereBetween('payment_date', [$dateFrom, $dateTo]); } if (!empty($filters['accounts'])) { $query->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $query->whereIn('payment_type', $filters['cash']); } }; $query->whereHas('paymentDistributions.payment', $applyPaymentFilters); if (!empty($filters['projects'])) { $query->whereHas('paymentDistributions', function ($query) use ($filters) { $query->whereIn('project_id', $filters['projects']); }); } $query->with([ 'paymentDistributions.project', 'paymentDistributions' => function ($query) use ($filters, $applyPaymentFilters) { if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } $query->whereHas('payment', $applyPaymentFilters); }, 'paymentDistributions.payment' => function ($query) use ($applyPaymentFilters) { $applyPaymentFilters($query); $query->with('contragent'); } ]); $article = $query->first(); $counterparties = $this->getUniqueCounterparties($article); $article->counterparties = $counterparties; return $article; } public function getUniqueCounterparties($article) { $uniqueCounterparties = $article->paymentDistributions ->pluck('payment.contragent') ->unique('id') ->values(); $counterpartyIds = $uniqueCounterparties->pluck('id')->toArray(); $paymentsIds = PaymentDistribution::query()->where('article_id', $article->id)->get('payment_id')->toArray(); return Counterparty::query() ->whereIn('id', $counterpartyIds) ->with(['payments' => function ($query) use ($paymentsIds) { $query->whereIn('id', $paymentsIds) ->with('distributions'); }]) ->get(); } public function getProjectCounterparties($project) { return $project->paymentDistributions ->filter(fn ($pd) => $pd->payment && $pd->payment->contragent) ->groupBy(fn ($pd) => $pd->payment->contragent->id) ->map(function ($distributions) { $counterparty = $distributions->first()->payment->contragent; $counterparty->payments = $distributions->map(fn ($pd) => $pd->payment); $counterparty->total_amount = $distributions->sum('amount'); return $counterparty; }) ->values(); } public function getUniqueCounterpariesToPayment($data) { $counterpartyIds = collect(); $paymentsIds = collect(); $data->each(function ($item) use (&$counterpartyIds, &$paymentsIds) { if ($item->payment) { $counterpartyIds->push($item->payment->counterparty_id); $paymentsIds->push($item->payment->id); } }); $counterpartyIds = $counterpartyIds->unique(); $paymentsIds = $paymentsIds->unique(); $counterparties = Counterparty::query() ->whereIn('id', $counterpartyIds) ->with(['payments' => function ($query) use ($paymentsIds) { $query->whereIn('id', $paymentsIds); }]) ->get(); return $counterparties; } public function sumTotalAmount($paymentDistributions) { $total = 0; foreach ($paymentDistributions as $article) { foreach ($article->paymentDistributions as $distribution) { if ($distribution->payment == null) { continue; } if (($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) && ($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value)) { $amount = (float)$distribution->amount; $total += $amount; } } } return $total; } public function getPaymentsMade($paymentsMadeInput) { $mapping = [ 'draft' => [ PaymentStatusEnum::STATUS_DRAFT->value, PaymentStatusEnum::STATUS_FINALIZE->value, PaymentStatusEnum::STATUS_FINALIZE_ONE_TWO->value, PaymentStatusEnum::STATUS_FINALIZE_TWO_TWO->value, ], 'approve' => [ PaymentStatusEnum::STATUS_APPROVE->value, PaymentStatusEnum::STATUS_AGREE_ONE_TWO->value, PaymentStatusEnum::STATUS_AGREE_TWO_TWO->value, ], 'awaiting_payment' => [ PaymentStatusEnum::STATUS_PAY->value, PaymentStatusEnum::STATUS_ISSUE->value, ], 'paid' => [ PaymentStatusEnum::STATUS_PAID->value, ], 'verified' => [ PaymentStatusEnum::STATUS_RECEIVED->value, PaymentStatusEnum::STATUS_ISSUED->value, ], 'awaiting_deposit' => [ PaymentStatusEnum::STATUS_SENT->value, PaymentStatusEnum::STATUS_MOVING->value, ], ]; $paymentsMade = []; if (isset($paymentsMadeInput)) { if (is_array($paymentsMadeInput)) { foreach ($paymentsMadeInput as $input) { if (isset($mapping[$input])) { $paymentsMade = array_merge($paymentsMade, $mapping[$input]); } } $paymentsMade = array_unique($paymentsMade); } elseif (isset($mapping[$paymentsMadeInput])) { $paymentsMade = $mapping[$paymentsMadeInput]; } } return array_values($paymentsMade); } public function getPaymentsMadeForApi(array $input): array { return array_values(array_unique($input)); } public function getScoreAndCashFilter($scoreAndCashInput) { $paymentTypes = []; if (isset($scoreAndCashInput)) { if ($scoreAndCashInput == 'cash') { $paymentTypes = [ PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value ]; } elseif ($scoreAndCashInput == 'score') { $paymentTypes = [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, ]; } elseif ($scoreAndCashInput == 'score_and_cash') { $paymentTypes = [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value, PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value ]; } } return $paymentTypes; } public function getFilter($projectsInput) { if (is_array($projectsInput)) { $flattened = array_reduce($projectsInput, function ($carry, $item) { if (is_string($item)) { $carry = array_merge($carry, explode(',', $item)); } elseif (is_array($item)) { $carry = array_merge($carry, $item); } elseif ($item !== null) { $carry[] = $item; } return $carry; }, []); return array_filter(array_map('trim', $flattened), 'is_numeric'); } elseif (is_string($projectsInput)) { return array_filter(array_map('trim', explode(',', $projectsInput)), 'is_numeric'); } elseif ($projectsInput !== null) { return [(string)$projectsInput]; } } public function excelExport($ids) { $export = new PaymentsExport(Payment::whereHas('distributions', function ($query) use ($ids): void { $query->whereIn('article_id', $ids); }), $ids); $filename = 'payments-' . date('Y-m-d-H-i-s') . '.xlsx'; Excel::store($export, $filename, 'public'); return $filename; } public function moveArticleOrArticleGroupInCashFlow($articleId, $newLine, $articleGroupId): void { if (isset($articleId) && isset($newLine)) { $article = Article::find($articleId); if (!$article) { return; } DB::transaction(function () use ($article, $newLine, $articleGroupId) { $oldGroupId = $article->article_group_id; $oldSort = $article->sort; if ($oldGroupId == (int)$articleGroupId) { if ($oldSort == $newLine) { $this->sortArticleAfterCreated($article->article_type, $articleGroupId, $newLine, $article); } if ($oldSort < $newLine) { $this->decrementSortArticleInGroup($article->article_type, $articleGroupId, $oldSort, $newLine); } else { $this->incrementSortArticleInGroup($article->article_type, $articleGroupId, $oldSort, $newLine); } } else { $query = Article::where('article_type', $article->article_type); if ($articleGroupId === null) { $query->whereNull('article_group_id'); } else { $query->where('article_group_id', $articleGroupId); } $query->where('sort', '>=', $newLine) ->increment('sort'); $this->sortArticleInGroupAfterDelete($oldGroupId, $oldSort); } $article->update([ 'article_group_id' => $articleGroupId, 'sort' => $newLine ]); }); } if (isset($articleGroupId) && isset($newLine)) { $articleGroup = ArticleGroup::find($articleGroupId); if (!$articleGroup) { return; } DB::transaction(function () use ($articleGroup, $newLine) { $where = [ 'article_type' => $articleGroup->article_type, 'sort' => $newLine, ]; $prevArticle = Article::where('article_group_id', $articleGroup->article_group_id) ->where($where) ->first(); if ($prevArticle) { $prevArticle->update(['sort' => $articleGroup->sort]); $articleGroup->update(['sort' => $newLine]); } else { $articleGroup->update(['sort' => $newLine]); } }); } } public function sumTotalExtradition($articleDebit) { $totalExtradition = 0.0; foreach ($articleDebit as $item) { foreach ($item->paymentDistributions as $distribution) { $amount = (float)$distribution->amount; if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) { $totalExtradition += $amount; } } } return $totalExtradition; } public function sortArticleAfterCreated($articleType, $articleGroupId, $newLine, $article) { Article::where('article_type', $articleType) ->where('article_group_id', $articleGroupId) ->where('sort', '>=', $newLine) ->where('id', '!=', $article->id) ->increment('sort'); } public function decrementSortArticleInGroup($articleType, $articleGroupId, $oldSort, $newLine) { return Article::where('article_type', $articleType) ->where('article_group_id', $articleGroupId) ->where('sort', '>', $oldSort) ->where('sort', '<=', $newLine) ->decrement('sort'); } public function incrementSortArticleInGroup($articleType, $articleGroupId, $oldSort, $newLine) { return Article::where('article_type', $articleType) ->where('article_group_id', $articleGroupId) ->where('sort', '<', $oldSort) ->where('sort', '>=', $newLine) ->increment('sort'); } public function sortArticleInGroupAfterDelete($oldGroupId, $oldSort) { return Article::where('article_group_id', $oldGroupId) ->where('sort', '>', $oldSort) ->decrement('sort'); } public function sortArticleWithoutGroupAfterDelete($oldSort) { return Article::where('article_group_id', null) ->where('sort', '>', $oldSort) ->decrement('sort'); } public function getUndistributedPayments($modelId, $type, $filters = []) { $query = Payment::query(); $query->where('model_id', $modelId); switch ($type) { case 'income': $query->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value]); if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } break; case 'expenses': $query->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value ]); if (!empty($filters['payments_made'])) { $query->whereIn('status', $filters['payments_made']); } break; default : break; } $this->applyPaymentDateFilter($query, $filters); $query->with(['organization', 'contragent', 'creator', 'account']); $query->whereHas('distributions', function ($subQuery) { $subQuery->whereNull('article_id'); }); $payments = $query->get(); $counterparties = Counterparty::whereHas( 'payments', function ($paymentQuery) use ($modelId, $type, $filters) { $paymentQuery->where('model_id', $modelId); switch ($type) { case 'income': $paymentQuery->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value ]); break; case 'expenses': $paymentQuery->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value, PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value ]); break; default: break; } if (!empty($filters['payments_made'])) { $paymentQuery->whereIn('status', $filters['payments_made']); } $this->applyPaymentDateFilter($paymentQuery, $filters); } )->whereHas( 'payments.distributions', function ($distributionQuery) { $distributionQuery->whereNull('article_id'); } )->with('payments.distributions')->get(); return [ 'count' => $query->count(), 'total_amount' => $query->sum('amount'), 'data' => $payments, 'by_counterparty' => ShowUndistributedPaymentsByCounterpartyResource::make($counterparties), ]; } public function applyPaymentDateFilter($query, $filters) { if (empty($filters['year'])) { return; } $year = (int) $filters['year']; $month = !empty($filters['month']) ? (int) $filters['month'] : null; $day = !empty($filters['day']) ? (int) $filters['day'] : null; $quarter = !empty($filters['quarter']) ? (int) $filters['quarter'] : null; $query->whereYear('payment_date', $year); if ($month && $day) { $query->whereMonth('payment_date', $month) ->whereDay('payment_date', $day); return; } if ($month) { $query->whereMonth('payment_date', $month); return; } if ($quarter) { $quarters = [ 1 => [1, 2, 3], 2 => [4, 5, 6], 3 => [7, 8, 9], 4 => [10, 11, 12], ]; if (isset($quarters[$quarter])) { $query->whereIn( DB::raw('EXTRACT(MONTH FROM payment_date)'), $quarters[$quarter] ); } } } }