/
var
/
www
/
html
/
back
/
app
/
Services
/
CashFlow
/
Upload File
HOME
<?php namespace App\Services\CashFlow; use App\Domain\Article\Enums\ArticleTypeEnum; use App\Domain\Payment\Enums\PaymentStatusEnum; use App\Domain\Payment\Enums\PaymentTypeEnum; use App\Http\Resources\CashFlowCreditResource; use App\Http\Resources\CashFlowCreditToMonthResource; use App\Http\Resources\CashFlowDebitResource; use App\Http\Resources\CashFlowDebitToMonthResource; use App\Http\Resources\NotDistributedPaymentResource; use App\Models\Article; use App\Models\ArticleGroup; use App\Models\Counterparty; use App\Models\PaymentDistribution; use App\Repositories\CashFlowIndex\Interfaces\PaymentDistributionsRepositoryInterface; use App\Repositories\CashFlowIndex\Interfaces\TotalAmountRepositoryInterface; use App\Responses\ResponseDto; use App\Services\CashFlowService; use Carbon\Carbon; use Illuminate\Support\Facades\Log; class ActiveTabMonthService { private $distributionsRepository; private $paymentRepository; public function __construct(PaymentDistributionsRepositoryInterface $paymentDistributionsRepository, TotalAmountRepositoryInterface $paymentRepository, protected CashFlowService $cashFlowService) { $this->distributionsRepository = $paymentDistributionsRepository; $this->paymentRepository = $paymentRepository; } public function getIndex(int $modelID, $filters) { $paymentDistributionsCredit = $this->distributionsRepository->getPaymentDistributions($modelID, $filters, ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value); $paymentDistributionsDebit = $this->distributionsRepository->getPaymentDistributions($modelID, $filters, ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value); $totalAmountCreditPayment = $this->paymentRepository->getTotalAmountPayment($modelID, $filters, $credit = true); $totalAmountDebitPayment = $this->paymentRepository->getTotalAmountPayment($modelID, $filters, $credit = false); $totalAmountCashCreditPayment = $this->paymentRepository->getTotalAmountCashPayment($modelID, $filters, $credit = true, $debitType = null); $totalAmountCashDebitMovingPayment = $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'); $paymentNotDistributionCredit = $this->distributionsRepository->getNotDistributionsPayment($modelID, $filters, $credit = true); $paymentNotDistributionDebit = $this->distributionsRepository->getNotDistributionsPayment($modelID, $filters, $credit = false); $totalCash = $this->cashFlowService->getTotalCash($filters, $modelID); $check = array_filter($filters, function ($value) { return $value !== null; }); if ($check) { $formattedDataCredit = $this->sortToMonth($paymentDistributionsCredit, true, $check); $formattedDataDebit = $this->sortToMonth($paymentDistributionsDebit, false, $check); $formattedOtherData = $this->sortToMonthOtherData($filters, $check, $modelID); $formattedTotalCash = $this->sortToMonthlyTotalCash($filters, $check, $modelID); $formattedNotDistributionCredit = $this->sortNotDistributedPaymentsToMonth($paymentNotDistributionCredit, true, $check); $formattedNotDistributionDebit = $this->sortNotDistributedPaymentsToMonth($paymentNotDistributionDebit, false, $check); } else { $formattedDataCredit = $this->sortToMonth($paymentDistributionsCredit, true, $check); $formattedDataDebit = $this->sortToMonth($paymentDistributionsDebit, false, $check); $formattedOtherData = $this->sortToMonthOtherData($filters, $check, $modelID); $formattedTotalCash = $this->sortToMonthlyTotalCash($filters, $check, $modelID); $formattedNotDistributionCredit = $this->sortNotDistributedPaymentsToMonth($paymentNotDistributionCredit, true, $check); $formattedNotDistributionDebit = $this->sortNotDistributedPaymentsToMonth($paymentNotDistributionDebit, false, $check); } $totalCredit = $this->sumTotalAmount($paymentDistributionsCredit); $totalDebit = $this->sumTotalAmount($paymentDistributionsDebit); $totalAmountToMonth = $this->totalAmountToMonth($formattedDataCredit, $formattedTotalCash, 'credit'); $totalAmountToMonth = $this->mergeDistributedAndNotDistributedByMonths($totalAmountToMonth, $formattedNotDistributionCredit); $totalAmountToMonthDebit = $this->totalAmountToMonth($formattedDataDebit, $formattedOtherData, 'debit'); $totalAmountToMonthDebit = $this->mergeDistributedAndNotDistributedByMonths($totalAmountToMonthDebit, $formattedNotDistributionCredit); $totalCashDetailes = $this->totalCasCreditToMonth($formattedTotalCash); $totalAmountCashToMonth = $this->totalCashDetails($formattedDataDebit); $newFormat = $this->newFormat($filters, $check); $startPeriod = $this->startPeriod($formattedDataCredit, $formattedDataDebit, $formattedTotalCash, $newFormat, $formattedOtherData); $startCash = $this->startCash($formattedTotalCash, $formattedDataDebit); $this->synx($startCash, $startPeriod); $totalCashDebit = $this->getTotalCashDebit($paymentDistributionsDebit); $groupsWithoutArticlesCredit = ArticleGroup::where(['article_type' => 'credit', 'model_id' => $modelID])->doesntHave('articles')->get(); $groupsWithoutArticlesDebit = ArticleGroup::where(['article_type' => 'debit', 'model_id' => $modelID])->doesntHave('articles')->get(); return new ResponseDto( data: [ 'header' => [ 'start_period' => [ 'amount' => $startPeriod, 'cash' => $startCash, ] ], 'credit' => [ 'static' => [ 'groups_without_articles' => $groupsWithoutArticlesCredit, 'total_amount' => $totalCredit + $totalAmountCreditPayment, 'total_cash' => $totalCash, 'articles' => CashFlowCreditResource::collection($paymentDistributionsCredit), 'not_distribution_payments_total_amount' => $totalAmountCreditPayment, 'cash' => $totalAmountCashCreditPayment, 'other_data' => [ 'total_cash' => $totalCash, ], ], 'dynamic' => [ 'total_amount' => $totalAmountToMonth, 'total_cash' => $totalCashDetailes, 'articles' => $formattedDataCredit, 'other_data' => $formattedTotalCash, 'not_distribution_payments' => $formattedNotDistributionCredit, ], ], 'debit' => [ 'static' => [ 'groups_without_articles' => $groupsWithoutArticlesDebit, 'total_amount' => $totalDebit + $totalAmountDebitPayment, 'total_cash_debit' => $totalCashDebit, 'articles' => CashFlowDebitResource::collection($paymentDistributionsDebit), 'not_distribution_payments_total_amount' => $totalAmountDebitPayment, 'other_data' => [ 'moving' => $totalMoving, 'commission' => $totalAmountCashDebitCommissionPayment, 'cash' => $totalAmountCashDebitMovingPayment, ], ], 'dynamic' => [ 'total_amount' => $totalAmountToMonthDebit, 'total_cash' => $totalAmountCashToMonth, 'articles' => $formattedDataDebit, 'other_data' => $formattedOtherData, 'not_distribution_payments' => $formattedNotDistributionDebit, ], ], 'footer' => [ 'end_period' => [ 'amount' => $startPeriod, 'cash' => $startCash, ] ], ], status: true ); } public function synx(&$startCash, $startPeriod) { foreach ($startPeriod as $year => $months) { if (!isset($startCash[$year])) { $startCash[$year] = []; } $periodMonths = array_keys($months); sort($periodMonths); $lastEndBalance = 0; foreach ($periodMonths as $month) { if (isset($startCash[$year][$month])) { $lastEndBalance = $startCash[$year][$month]['end_balance']; } else { $startCash[$year][$month] = [ 'start_balance' => $lastEndBalance, 'end_balance' => $lastEndBalance, ]; } } ksort($startCash[$year]); } } public function startCash($formattedTotalCash, $formattedDataDebit) { $newCollection = []; foreach ($formattedTotalCash as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($formattedDataDebit as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($newCollection as $year => &$months) { ksort($months); } unset($months); $collection = []; $previousBalance = 0; foreach ($newCollection as $year => $months) { foreach ($months as $month => $records) { $income = 0; $expense = 0; foreach ($records as $key => $record) { if ((!is_object($record) && ($key == 'total_cash'))) { $income += $record; } if (is_object($record)) { $item = $record->resolve(); if ($item['type'] == ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value) { $expense += (float)$item['total_extradition']; } } } $startBalance = $previousBalance; $endBalance = $startBalance + $income - $expense; if (!isset($collection[$year])) { $collection[$year] = []; } $collection[$year][$month] = [ 'start_balance' => $startBalance, 'end_balance' => $endBalance ]; $previousBalance = $endBalance; } } return $collection; } public function getTotalCashDebit($paymentDistributions) { $totalExtradition = 0; foreach ($paymentDistributions as $article) { foreach ($article->paymentDistributions as $distribution) { if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) { $amount = (float)$distribution->amount; $totalExtradition += $amount; } } } return $totalExtradition; } public function totalCashDetails($formattedDataDebit) { $monthlyExtradition = []; foreach ($formattedDataDebit as $year => $months) { if (!isset($monthlyExtradition[$year])) { $monthlyExtradition[$year] = []; } foreach ($months as $month => $items) { $totalExtradition = 0; foreach ($items as $item) { $arr = $item->toArray(request()); $totalExtradition += $arr['total_extradition'] ?? 0; } $monthlyExtradition[$year][$month] = $totalExtradition; } } return $monthlyExtradition; } public function totalCasCreditToMonth($formattedTotalCash) { $result = []; foreach ($formattedTotalCash as $year => $months) { foreach ($months as $month => $items) { if (isset($items['total_cash'])) { $cashValue = (float)$items['total_cash']; if (isset($result[$year][$month])) { $result[$year][$month] += $cashValue; } else { $result[$year][$month] = $cashValue; } } } } return $result; } public function totalAmountToMonth($formattedDataCredit, $formattedTotalCash, $type) { $result = []; foreach ($formattedDataCredit as $year => $months) { $yearTotalAmount = 0; foreach ($months as $month => $items) { $monthTotalAmount = 0; foreach ($items as $item) { $monthTotalAmount += (float)$item->total_amount; } $yearTotalAmount += $monthTotalAmount; if (!isset($result[$year])) { $result[$year] = []; } $result[$year][$month] = $monthTotalAmount; } $result[$year]['total'] = $yearTotalAmount; } // foreach ($formattedTotalCash as $year => $months) { // foreach ($months as $month => $items) { // if (isset($items['total_cash'])) { // $cashValue = intval($items['total_cash']); // if (isset($result[$year][$month])) { // $result[$year][$month] += $cashValue; // } else { // $result[$year][$month] = $cashValue; // } //// $result[$year]['total'] += $cashValue; // } // } // } return $result; } public function startPeriod($formattedDataCredit, $formattedDataDebit, $formattedTotalCash, $formattedOtherData, $formattedCommission) { $newCollection = []; foreach ($formattedDataCredit as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($formattedDataDebit as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($formattedTotalCash as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($formattedOtherData as $year => $months) { foreach ($months as $monthIndex => $monthData) { if (isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = array_merge($newCollection[$year][$monthIndex], $monthData); } else { $newCollection[$year][$monthIndex] = $monthData; } } } foreach ($formattedCommission as $year => $months) { foreach ($months as $monthIndex => $monthData) { $value = is_array($monthData) ? ($monthData['total_cash'] ?? null) : ($monthData->total_cash ?? null); if (!isset($newCollection[$year][$monthIndex])) { $newCollection[$year][$monthIndex] = []; } $newCollection[$year][$monthIndex]['total_moving'] = $value; } } foreach ($newCollection as $year => &$months) { ksort($months); } unset($months); $collection = []; $previousBalance = 0; foreach ($newCollection as $year => $months) { foreach ($months as $month => $records) { $income = 0; $expense = 0; foreach ($records as $key => $record) { if ((!is_object($record) && ($key == 'total_cash'))) { $income += $record; } if ((!is_object($record) && ($key == 'total_moving'))) { $expense += $record; } if (is_object($record)) { if ($record->article->article_type == "credit") { $income += (float)$record->total_amount; } else { $expense += (float)$record->total_amount; } } } $startBalance = $previousBalance; $endBalance = $startBalance + $income - $expense; if (!isset($collection[$year])) { $collection[$year] = []; } $collection[$year][$month] = [ 'start_balance' => $startBalance, 'end_balance' => $endBalance ]; $previousBalance = $endBalance; } } return $collection; } public function getArticleShow($modelId, $articleId, $year, $month, $filters) { $query = Article::query() ->where('model_id', $modelId) ->where('id', $articleId); $applyPaymentFilters = function ($query) use ($year, $month, $filters) { $query->whereYear('payment_date', $year) ->whereMonth('payment_date', $month) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value); 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->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) ->with('contragent'); } ]); $article = $query->first(); $counterparties = $this->getUniqueCounterparties($article); $article->counterparties = $counterparties; return $article; } public function getArticlesGroupShow($modelId, $articleGroupId, $year, $month, $filters) { $query = ArticleGroup::query() ->where('model_id', $modelId) ->where('id', $articleGroupId); $articlesCallback = function ($query) use ($year, $month, $filters) { $query->has('paymentDistributions')->with([ 'paymentDistributions' => function ($query) use ($year, $month, $filters) { $query->whereHas('payment', function ($q) use ($year, $month) { $q->whereYear('payment_date', $year) ->whereMonth('payment_date', $month) ->whereNotIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value ]); }); 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 ($year, $month, $filters) { $query->whereYear('payment_date', $year) ->whereMonth('payment_date', $month) ->whereNotIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value ]) ->with('contragent'); 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' ]); }; $query->with(['articles' => $articlesCallback]); $articleGroups = $query->first(); $counterpartyIds = collect(); $paymentsIds = collect(); $articleGroups->articles->each(function ($article) use (&$counterpartyIds, &$paymentsIds) { $uniqueCounterparties = $article->paymentDistributions ->pluck('payment.contragent') ->filter() ->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 ($q) use ($paymentsIds) { $q->whereIn('id', $paymentsIds) ->with('distributions.project'); }]) ->get(); $articleGroups->setRelation('counterparties', $counterparties); return $articleGroups; } public function getOtherDataShow($modelId, $year, $month, $type, $filters) { $baseQuery = function ($query) use ($year, $month) { $query->whereYear('payment_date', $year) ->whereMonth('payment_date', $month) ->with('contragent'); }; $actualAwareBaseQuery = function ($query) use ($year, $month) { $query->where(function ($q) use ($year, $month) { $q->where(function ($qActual) use ($year, $month) { $qActual->whereNotNull('actual_date') ->whereYear('actual_date', $year) ->whereMonth('actual_date', $month); })->orWhere(function ($qPayment) use ($year, $month) { $qPayment->whereNull('actual_date') ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); })->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, $year, $month, $modelId, $filters) { $query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId]) ->where(function ($q) use ($year, $month) { $q->where(function ($qPayment) use ($year, $month) { $qPayment->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }) ->with('contragent'); 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, $year, $month, $modelId, $filters) { $query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId]) ->where(function ($q) use ($year, $month) { $q->where(function ($qPayment) use ($year, $month) { $qPayment->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); 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, $year, $month, $modelId, $filters) { $query->where('model_id', $modelId) ->where(function ($q) use ($year, $month) { $q->where(function ($qMoving) use ($year, $month) { $qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where(function ($qPayment) use ($year, $month) { $qPayment->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); })->orWhere(function ($qOther) use ($year, $month) { $qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }) ->with('contragent'); 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, $year, $month, $modelId, $filters) { $query->where('model_id', $modelId) ->where(function ($q) use ($year, $month) { $q->where(function ($qMoving) use ($year, $month) { $qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where(function ($qPayment) use ($year, $month) { $qPayment->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); })->orWhere(function ($qOther) use ($year, $month) { $qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); 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': $query->where('cashbox', '!=', null) ->with(['payment' => function ($query) use ($baseQuery, $modelId, $year, $month, $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, $year, $month, $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 ($actualAwareBaseQuery, $modelId, $year, $month, $filters) { $query->where(function ($q) use ($modelId, $year, $month) { $q->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, 'model_id' => $modelId]) ->orWhere(function ($q2) use ($modelId, $year, $month) { $q2->where([ 'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId, 'status' => PaymentStatusEnum::STATUS_RECEIVED->value ]); }); }); $query->where(function ($q) use ($year, $month) { $q->where(function ($qActual) use ($year, $month) { $qActual->whereNotNull('actual_date') ->whereYear('actual_date', $year) ->whereMonth('actual_date', $month); })->orWhere(function ($qPayment) use ($year, $month) { $qPayment->whereNull('actual_date') ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); 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']); } $actualAwareBaseQuery($query); }]) ->whereHas('payment', function ($query) use ($actualAwareBaseQuery, $modelId, $year, $month, $filters) { $query->where(function ($q) use ($modelId, $year, $month) { $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]); }); }); $query->where(function ($q) use ($year, $month) { $q->where(function ($qActual) use ($year, $month) { $qActual->whereNotNull('actual_date') ->whereYear('actual_date', $year) ->whereMonth('actual_date', $month); })->orWhere(function ($qPayment) use ($year, $month) { $qPayment->whereNull('actual_date') ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); 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']); } $actualAwareBaseQuery($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 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 sortToMonthlyTotalCash($filters, $check, $modelID) { $query = PaymentDistribution::query() ->whereHas('payment', function ($q) use ($modelID) { $q->where('model_id', $modelID); }); if ($check) { if (!empty($filters['date_from'])) { $dateFrom = $filters['date_from']; $dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now(); // Добавляем приемы по payment_date и перемещения по actual_date $query->whereHas('payment', function ($query) use ($dateFrom, $dateTo) { $query->where(function ($q) use ($dateFrom, $dateTo) { // Приемы по payment_date $q->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->whereBetween('payment_date', [$dateFrom, $dateTo]); })->orWhere(function ($q2) use ($dateFrom, $dateTo) { // Перемещения по actual_date $q2->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereNotNull('actual_date') ->whereBetween('actual_date', [$dateFrom, $dateTo]); }); }); } if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']) ->whereHas('payment', function ($query) { $query->where(function ($q) { $q->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value); })->orWhere(function ($q2) { $q2->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereNotNull('actual_date'); }); }); } if (!empty($filters['accounts'])) { $query->whereHas('payment', function ($query) use ($filters) { $query->whereIn('account_id', $filters['accounts']); }); } if (!empty($filters['payments_made'])) { $query->whereHas('payment', function ($query) use ($filters) { $query->whereIn('status', $filters['payments_made']); }); } } else { $query->whereHas('payment', function ($query) { $query->where(function ($q) { $q->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value); })->orWhere(function ($q2) { $q2->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereNotNull('actual_date'); }); }); } $paymentDistributions = $query->get(); $monthlyCollection = []; foreach ($paymentDistributions as $distribution) { $payment = $distribution->payment; if (!$payment) continue; // Для приемов используем payment_date и amount if ($payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value && isset($payment->payment_date)) { $paymentDate = $payment->payment_date; $year = date('Y', strtotime($paymentDate)); $month = (int)date('m', strtotime($paymentDate)); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = []; } if (!isset($monthlyCollection[$year][$month])) { $monthlyCollection[$year][$month] = [ 'total_cash' => 0, ]; } $monthlyCollection[$year][$month]['total_cash'] += $distribution->amount; } // Для перемещений используем actual_date и cashbox elseif ($payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_MOVING->value && $payment->status == PaymentStatusEnum::STATUS_RECEIVED->value && isset($payment->actual_date)) { $paymentDate = $payment->actual_date; $year = date('Y', strtotime($paymentDate)); $month = (int)date('m', strtotime($paymentDate)); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = []; } if (!isset($monthlyCollection[$year][$month])) { $monthlyCollection[$year][$month] = [ 'total_cash' => 0, ]; } // Используем cashbox для перемещений if (isset($distribution->cashbox)) { $monthlyCollection[$year][$month]['total_cash'] += $distribution->cashbox; } } } if ($check) { foreach ($monthlyCollection as $year => $months) { foreach ($months as $month => $items) { if ($items['total_cash'] == 0) { unset($monthlyCollection[$year][$month]); } } if (empty($monthlyCollection[$year])) { unset($monthlyCollection[$year]); } } } return $monthlyCollection; } public function sortToMonthOtherData($filters, $check, $modelId) { $query = PaymentDistribution::query(); if ($check) { $query->whereHas('payment', function ($q) use ($filters, $modelId) { $q->where('model_id', $modelId); if (!empty($filters['date_from'])) { $q->whereBetween('payment_date', [ $filters['date_from'], $filters['date_to'] ?? Carbon::now() ]); } if (!empty($filters['accounts'])) { $q->whereIn('account_id', $filters['accounts']); } if (!empty($filters['payments_made'])) { $q->whereIn('status', $filters['payments_made']); } if (!empty($filters['cash'])) { $q->whereIn('payment_type', $filters['cash']); } }); if (!empty($filters['projects'])) { $query->whereIn('project_id', $filters['projects']); } $query->with('payment'); } else { $query->with('payment'); } $paymentDistributions = $query->get(); $monthlyCollection = []; foreach ($paymentDistributions as $distribution) { if (isset($distribution->payment->payment_date)) { if ($distribution->payment->model_id == $modelId) { $paymentDate = $distribution->payment->payment_date; $year = date('Y', strtotime($paymentDate)); $month = (int)date('m', strtotime($paymentDate)); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = array_fill(1, 12, [ 'total_cash' => 0, 'total_commission' => 0, 'total_moving' => 0]); } $monthlyCollection[$year][$month]['total_commission'] += $distribution->comission; if ($distribution->payment->payment_type === PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) { $monthlyCollection[$year][$month]['total_cash'] += $distribution->amount; if (!is_null($distribution->cashbox)) { $monthlyCollection[$year][$month]['total_moving'] += $distribution->cashbox; } } } } } if ($check) { foreach ($monthlyCollection as $year => $months) { foreach ($months as $month => $items) { if (($items['total_cash'] == 0) && ($items['total_commission'] == 0) && ($items['total_moving'] == 0)) { unset($monthlyCollection[$year][$month]); } } if (empty($monthlyCollection[$year])) { unset($monthlyCollection[$year]); } } } return $monthlyCollection; } public function newFormat($filters, $check) { $query = PaymentDistribution::query(); if ($check) { if (!empty($filters['date_from'])) { if (empty($filters['date_to'])) { $dateTo = Carbon::now(); } else { $dateTo = $filters['date_to']; } $query->with(['payment' => function ($query) use ($filters, $dateTo) { $query->whereBetween('payment_date', [$filters, $dateTo]); }]); } if (!empty($filters['cash'])) { $query->whereHas('payment', function ($query) use ($filters) { $query->whereIn('payment_type', $filters['cash']); }); } } else { $query->with('payment'); } $paymentDistributions = $query->get(); $monthlyCollection = []; foreach ($paymentDistributions as $distribution) { if (isset($distribution->payment->payment_date)) { $paymentDate = $distribution->payment->payment_date; $year = date('Y', strtotime($paymentDate)); $month = (int)date('m', strtotime($paymentDate)); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = array_fill(1, 12, [ 'total_debit_cash' => 0, ]); } if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) { $monthlyCollection[$year][$month]['total_debit_cash'] += $distribution->amount; } } } if ($check) { foreach ($monthlyCollection as $year => $months) { foreach ($months as $month => $items) { if ($items['total_debit_cash'] == 0) { unset($monthlyCollection[$year][$month]); } } if (empty($monthlyCollection[$year])) { unset($monthlyCollection[$year]); } } } return $monthlyCollection; } protected function sortToMonth($paymentDistributions, $credit, $filter) { $monthlyCollection = []; foreach ($paymentDistributions as $payment) { if (isset($payment->paymentDistributions)) { foreach ($payment->paymentDistributions as $distribution) { if (isset($distribution->payment->payment_date)) { $paymentDate = $distribution->payment->payment_date; $year = date('Y', strtotime($paymentDate)); $month = $this->getMonth($paymentDate); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = [ 1 => [], 2 => [], 3 => [], 4 => [], 5 => [], 6 => [], 7 => [], 8 => [], 9 => [], 10 => [], 11 => [], 12 => [] ]; } $articleId = $distribution->article_id; $found = false; if (($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) && ($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)) { $distribution->total_amount = $distribution->amount; } if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) { $distribution->total_extradition = $distribution->amount; } else { $distribution->total_extradition = 0; } foreach ($monthlyCollection[$year][$month] as &$item) { if ($item->article_id == $articleId) { if (($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) && ($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)) { $item->total_amount += $distribution->total_amount; } $item->total_extradition += $distribution->total_extradition; $found = true; break; } } if (!$found) { if ($credit) { $monthlyCollection[$year][$month][] = new CashFlowCreditToMonthResource($distribution); } else { $monthlyCollection[$year][$month][] = new CashFlowDebitToMonthResource($distribution); } } } } } } if ($filter) { foreach ($monthlyCollection as $year => $months) { foreach ($months as $month => $items) { if (empty($items)) { unset($monthlyCollection[$year][$month]); } } if (empty($monthlyCollection[$year])) { unset($monthlyCollection[$year]); } } } return $monthlyCollection; } 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; } private function getMonth($date) { return date('n', strtotime($date)); } public function getIncomeAndExpensesToMonthShow($modelId, $type, $year, $month, $filters = []) { $query = PaymentDistribution::query(); $statuses = $filters['payments_made'] ?? [PaymentStatusEnum::STATUS_RECEIVED->value]; $query->whereHas('payment', function ($query) use ($year, $month, $statuses) { $query->whereYear('payment_date', $year) ->whereMonth('payment_date', $month) ->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->where(function ($q) use ($statuses) { $q->whereIn('status', $statuses) ->orWhere(function ($q) { $q->where('status', PaymentStatusEnum::STATUS_SENT->value) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value); }); }); }); switch ($type) { case 'credit': $query->with(['article' => function ($query) use ($modelId) { $query->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value, 'model_id' => $modelId ]); }, 'payment' => function ($paymentQuery) { $paymentQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value) ->where(function ($q) { $q->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->orWhere(function ($q) { $q->where('status', PaymentStatusEnum::STATUS_SENT->value) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value); }); }) ->with('contragent'); }])->whereHas('article', function ($query) use ($modelId) { $query->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_CREDIT->value, 'model_id' => $modelId ]); }); break; case 'debit': $query->with(['article' => function ($query) use ($modelId) { $query ->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value, 'model_id' => $modelId ]); }, 'payment.contragent']) ->whereHas('article', function ($query) use ($modelId) { $query->where([ 'article_type' => ArticleTypeEnum::ARTICLE_TYPE_DEBIT->value, 'model_id' => $modelId ]); }); break; default: break; } return $query->get(); } public function getCashIncomeToMonthShow(int $modelId, int $year, int $month) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId, $year, $month) { $query ->where('model_id', $modelId) ->where('status', PaymentStatusEnum::STATUS_RECEIVED->value) ->whereIn('payment_type', [ PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value, PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, ]) ->where(function ($q) use ($year, $month) { $q->where(function ($q) use ($year, $month) { $q->whereNotNull('actual_date') ->whereYear('actual_date', $year) ->whereMonth('actual_date', $month); }); $q->orWhere(function ($q) use ($year, $month) { $q->whereNull('actual_date') ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); }) ->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 getReceptionIncomeToMonthShow(int $modelId, int $year, int $month, array $statuses = []) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId, $year, $month, $statuses) { $query->where('model_id', $modelId) ->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value); if (!empty($statuses)) { $query->whereIn('status', $statuses); } $query->where(function ($q) use ($year, $month) { $q->where(function ($q) use ($year, $month) { $q->whereNotNull('actual_date') ->whereYear('actual_date', $year) ->whereMonth('actual_date', $month); }); $q->orWhere(function ($q) use ($year, $month) { $q->whereNull('actual_date') ->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }); }) ->with([ 'payment.contragent', 'article', ]); $collection = $query->get(); $collection->each(function ($distribution) { $distribution->amount = $distribution->cashbox ?? $distribution->amount; }); return $collection; } public function getUndistributedIncomeShowByMonths($modelId, $year, $month, $paymentsMade) { $query = PaymentDistribution::query() ->whereHas('payment', function ($query) use ($modelId, $year, $month, $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); } $query->where(function ($q) use ($year, $month) { $q->whereYear('payment_date', $year) ->whereMonth('payment_date', $month); }); }) ->with([ 'payment.contragent', 'article', ]); return $query->get(); } protected function sortNotDistributedPaymentsToMonth($paymentDistributions, $credit, $filter) { $monthlyCollection = []; foreach ($paymentDistributions as $distribution) { if (!isset($distribution->payment->payment_date)) { continue; } $paymentDate = $distribution->payment->payment_date; $year = date('Y', strtotime($paymentDate)); $month = $this->getMonth($paymentDate); if (!isset($monthlyCollection[$year])) { $monthlyCollection[$year] = [ 1 => [], 2 => [], 3 => [], 4 => [], 5 => [], 6 => [], 7 => [], 8 => [], 9 => [], 10 => [], 11 => [], 12 => [] ]; } $amount = $credit ? $distribution->amount : $distribution->amount; $monthlyCollection[$year][$month]['total_amount'] = ($monthlyCollection[$year][$month]['total_amount'] ?? 0) + $amount; } if ($filter) { foreach ($monthlyCollection as $year => $months) { foreach ($months as $month => $items) { if (empty($items)) { unset($monthlyCollection[$year][$month]); } } if (empty($monthlyCollection[$year])) { unset($monthlyCollection[$year]); } } } return $monthlyCollection; } private function mergeDistributedAndNotDistributedByMonths(array $totalAmount, array $notDistributedPayments): array { foreach ($notDistributedPayments as $year => $periods) { foreach ($periods as $period => $data) { if ($period === 'total') continue; $amount = $data['total_amount'] ?? 0; if (!isset($totalAmount[$year][$period])) { $totalAmount[$year][$period] = 0; } $totalAmount[$year][$period] += $amount; } } foreach ($totalAmount as $year => $periods) { $totalAmount[$year]['total'] = array_sum(array_filter( $periods, fn($k) => $k !== 'total', ARRAY_FILTER_USE_KEY )); } return $totalAmount; } }