/var/www/html/back/app/Services/CashFlow/ActiveTabMonthService.php
<?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;
}
}