File "ActiveTabQuarterService.php"
Full Path: /var/www/html/back/app/Services/CashFlow/ActiveTabQuarterService.php
File size: 77.05 KB
MIME-type: text/x-php
Charset: utf-8
<?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\DB;
class ActiveTabQuarterService
{
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');
$groupsWithoutArticlesCredit = ArticleGroup::where(['article_type' => 'credit', 'model_id' => $modelID])->doesntHave('articles')->get();
$groupsWithoutArticlesDebit = ArticleGroup::where(['article_type' => 'debit', 'model_id' => $modelID])->doesntHave('articles')->get();
$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->sortToQuarter($paymentDistributionsCredit, true, $check);
$formattedDataDebit = $this->sortToQuarter($paymentDistributionsDebit, false, $check);
$formattedCommission = $this->sortToQuarterOtherDataDebit($filters, $check, $modelID);
$formattedTotalCash = $this->sortToQuarterTotalCash($filters, $check, $modelID);
$formattedNotDistributionCredit = $this->sortNotDistributedPaymentsToQuarter($paymentNotDistributionCredit, true, $check);
$formattedNotDistributionDebit = $this->sortNotDistributedPaymentsToQuarter($paymentNotDistributionDebit, false, $check);
} else {
$formattedDataCredit = $this->sortToQuarter($paymentDistributionsCredit, true, $check);
$formattedDataDebit = $this->sortToQuarter($paymentDistributionsDebit, false, $check);
$formattedCommission = $this->sortToQuarterOtherDataDebit($filters, $check, $modelID);
$formattedTotalCash = $this->sortToQuarterTotalCash($filters, $check, $modelID);
$formattedNotDistributionCredit = $this->sortNotDistributedPaymentsToQuarter($paymentNotDistributionCredit, true, $check);
$formattedNotDistributionDebit = $this->sortNotDistributedPaymentsToQuarter($paymentNotDistributionDebit, false, $check);
}
$totalAmountToQuarter = $this->totalAmountToQuarter($formattedDataCredit, $formattedTotalCash, 'credit');
$totalAmountToQuarter = $this->mergeDistributedAndNotDistributedByQuarter($totalAmountToQuarter, $formattedNotDistributionCredit);
$totalAmountToQuarterDebit = $this->totalAmountToQuarter($formattedDataDebit, $formattedCommission, 'debit');
$totalAmountToQuarterDebit = $this->mergeDistributedAndNotDistributedByQuarter($totalAmountToQuarterDebit, $formattedNotDistributionDebit);
$totalCredit = $this->sumTotalAmount($paymentDistributionsCredit);
$totalDebit = $this->sumTotalAmount($paymentDistributionsDebit);
$totalCashDetailes = $this->totalCasCreditToQuarter($formattedTotalCash);
$ttlCash = $this->totalCashDetails($formattedDataDebit);
$newFormat = $this->newFormat($filters, $check);
$startPeriod = $this->startPeriod($formattedDataCredit, $formattedDataDebit, $formattedTotalCash, $newFormat, $formattedCommission);
$totalCashDebit = $this->getTotalCashDebit($paymentDistributionsDebit);
$startCash = $this->startCash($formattedTotalCash, $formattedDataDebit);
$toQuarter = $this->sortToQuarterAmount($formattedDataCredit, $formattedDataDebit);
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' => $totalAmountToQuarter,
'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' => $totalAmountToQuarterDebit,
'total_cash' => $ttlCash,
'articles' => $formattedDataDebit,
'other_data' => $formattedCommission,
'not_distribution_payments' => $formattedNotDistributionDebit,
],
],
'footer' => [
'end_period' => [
'amount' => $startPeriod,
'cash' => $startCash,
]
],
],
status: true
);
}
public function startCash($formattedTotalCash, $formattedDataDebit)
{
$newCollection = [];
foreach ($formattedTotalCash as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($formattedDataDebit as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($newCollection as $year => &$quarters) {
ksort($quarters);
}
unset($quarters);
$collection = [];
$previousBalance = 0;
foreach ($newCollection as $year => $quarters) {
foreach ($quarters as $quarter => $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][$quarter] = [
'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 != null) {
if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value) {
$amount = (float)$distribution->amount;
$totalExtradition += $amount;
}
}
}
}
return $totalExtradition;
}
public function newFormat($filters, $check)
{
$query = PaymentDistribution::query();
if ($check) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now();
$query->with(['payment' => function ($query) use ($dateFrom, $dateTo) {
$query->whereBetween('payment_date', [$dateFrom, $dateTo]);
}]);
}
if (!empty($filters['projects'])) {
$query->whereIn('project_id', $filters['projects']);
}
if (!empty($filters['accounts'])) {
$query->whereHas('payment', function ($query) use ($filters) {
$query->whereIn('account_id', $filters['accounts']);
});
}
if (!empty($filters['cash'])) {
$query->whereHas('payment', function ($query) use ($filters) {
$query->whereIn('payment_type', $filters['cash']);
});
}
} else {
$query->with('payment');
}
$paymentDistributions = $query->get();
$quarterlyCollection = [];
foreach ($paymentDistributions as $distribution) {
if (isset($distribution->payment->payment_date)) {
$paymentDate = $distribution->payment->payment_date;
$year = date('Y', strtotime($paymentDate));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [
'total_debit_cash' => 0,
],
2 => [
'total_debit_cash' => 0,
],
3 => [
'total_debit_cash' => 0,
],
4 => [
'total_debit_cash' => 0,
]
];
}
if ($distribution->payment->payment_type == PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) {
$quarterlyCollection[$year][$quarter]['total_debit_cash'] += $distribution->amount;
}
}
}
if ($check) {
foreach ($quarterlyCollection as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if ($items['total_debit_cash'] == 0) {
unset($quarterlyCollection[$year][$quarter]);
}
}
if (empty($quarterlyCollection[$year])) {
unset($quarterlyCollection[$year]);
}
}
}
return $quarterlyCollection;
}
public function startPeriod($formattedDataCredit, $formattedDataDebit, $formattedTotalCash, $formattedOtherData, $formattedCommission)
{
$newCollection = [];
foreach ($formattedDataCredit as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($formattedDataDebit as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($formattedTotalCash as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($formattedOtherData as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
if (isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = array_merge($newCollection[$year][$quarterIndex], $quarterData);
} else {
$newCollection[$year][$quarterIndex] = $quarterData;
}
}
}
foreach ($formattedCommission as $year => $quarters) {
foreach ($quarters as $quarterIndex => $quarterData) {
$value = is_array($quarterData) ? ($quarterData['total_cash'] ?? null) : ($quarterData->total_cash ?? null);
if (!isset($newCollection[$year][$quarterIndex])) {
$newCollection[$year][$quarterIndex] = [];
}
$newCollection[$year][$quarterIndex]['total_moving'] = $value;
}
}
foreach ($newCollection as $year => &$quarters) {
ksort($quarters);
}
unset($quarters);
$collection = [];
$previousBalance = 0;
foreach ($newCollection as $year => $quarters) {
foreach ($quarters as $quarter => $values) {
$income = 0;
$expense = 0;
foreach ($values as $key => $item) {
if ((!is_object($item) && ($key == 'total_cash'))) {
$income += $item;
}
if ((!is_object($item) && ($key == 'total_moving'))) {
$expense += $item;
}
if (is_object($item)) {
if ($item->article->article_type == "credit") {
$income += (float)$item->total_amount;
} else {
$expense += (float)$item->total_amount;
}
}
}
$startBalance = $previousBalance;
$endBalance = $startBalance + $income - $expense;
if (!isset($collection[$year])) {
$collection[$year] = [];
}
$collection[$year][$quarter] = [
'start_balance' => $startBalance,
'end_balance' => $endBalance
];
$previousBalance = $endBalance;
}
}
return $collection;
}
public function totalCashDetails($formattedDataDebit)
{
$quarterExtradition = [];
foreach ($formattedDataDebit as $year => $quarters) {
if (!isset($quarterExtradition[$year])) {
$quarterExtradition[$year] = [];
}
foreach ($quarters as $quarter => $items) {
$totalExtradition = 0;
foreach ($items as $item) {
$arr = $item->toArray(request());
$totalExtradition += $arr['total_extradition'] ?? 0;
}
$quarterExtradition[$year][$quarter] = $totalExtradition;
}
}
return $quarterExtradition;
}
public function totalCasCreditToQuarter($formattedTotalCash)
{
$result = [];
foreach ($formattedTotalCash as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if (isset($items['total_cash'])) {
$cashValue = (float)$items['total_cash'];
if (isset($result[$year][$quarter])) {
$result[$year][$quarter] += $cashValue;
} else {
$result[$year][$quarter] = $cashValue;
}
}
}
}
return $result;
}
public function totalAmountToQuarter($formattedDataCredit, $formattedTotalCash, $type)
{
$result = [];
foreach ($formattedDataCredit as $year => $quarters) {
$yearTotalAmount = 0;
foreach ($quarters as $quarter => $items) {
$quarterTotalAmount = 0;
foreach ($items as $item) {
$quarterTotalAmount += (float)$item->total_amount;
}
$yearTotalAmount += $quarterTotalAmount;
if (!isset($result[$year])) {
$result[$year] = [];
}
$result[$year][$quarter] = $quarterTotalAmount;
}
$result[$year]['total'] = $yearTotalAmount;
}
// foreach ($formattedTotalCash as $year => $quarters) {
// foreach ($quarters as $quarter => $items) {
// if (isset($items['total_cash'])) {
// $cashValue = intval($items['total_cash']);
// if (isset($result[$year][$quarter])) {
// $result[$year][$quarter] += $cashValue;
// } else {
// $result[$year][$quarter] = $cashValue;
// }
//// $result[$year]['total'] += $cashValue;
// }
// }
// }
return $result;
}
public function sortToQuarterAmount($formattedDataCredit, $formattedDataDebit)
{
$combinedData = [
'credit_by_quarter' => [],
'debit_by_quarter' => []
];
return $combinedData;
}
public function getArticleShow($modelId, $articleId, $year, $quarter, $filters)
{
$query = Article::query()
->where('model_id', $modelId)
->where('id', $articleId);
$startMonth = ($quarter - 1) * 3 + 1;
$endMonth = $quarter * 3;
$applyPaymentFilters = function ($query) use ($year, $startMonth, $endMonth, $filters) {
$query->whereYear('payment_date', $year)
->whereMonth('payment_date', '>=', $startMonth)
->whereMonth('payment_date', '<=', $endMonth)
->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_MOVING->value)
->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->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, $quarter, $filters)
{
$query = ArticleGroup::query()
->where('model_id', $modelId)
->where('id', $articleGroupId);
$articlesCallback = function ($query) use ($year, $quarter, $filters) {
$startMonth = ($quarter - 1) * 3 + 1;
$endMonth = $quarter * 3;
$query->has('paymentDistributions')->with([
'paymentDistributions' => function ($query) use ($year, $startMonth, $endMonth, $filters) {
$query->whereHas('payment', function ($query) use ($year, $startMonth, $endMonth) {
$query->whereYear('payment_date', $year)
->whereMonth('payment_date', '>=', $startMonth)
->whereMonth('payment_date', '<=', $endMonth)
->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->whereHas('payment', function ($q) use ($filters, $dateFrom, $dateTo) {
$q->whereBetween('payment_date', [$dateFrom, $dateTo]);
});
}
if (!empty($filters['projects'])) {
$query->whereIn('project_id', $filters['projects']);
}
if (!empty($filters['accounts'])) {
$query->whereHas('payment', function ($q) use ($filters) {
$q->whereIn('account_id', $filters['accounts']);
});
}
if (!empty($filters['payments_made'])) {
$query->whereHas('payment', function ($q) use ($filters) {
$q->whereIn('status', $filters['payments_made']);
});
}
if (!empty($filters['cash'])) {
$query->whereHas('payment', function ($q) use ($filters) {
$q->whereIn('payment_type', $filters['cash']);
});
}
},
'paymentDistributions.payment' => function ($query) use ($year, $startMonth, $endMonth, $filters) {
$query->whereYear('payment_date', $year)
->whereMonth('payment_date', '>=', $startMonth)
->whereMonth('payment_date', '<=', $endMonth)
->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');
if (!empty($filters['accounts'])) {
$query->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$query->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$query->whereIn('payment_type', $filters['cash']);
}
},
'paymentDistributions.project',
]);
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to'];
$query->whereHas('paymentDistributions.payment', function ($q) use ($filters, $dateFrom, $dateTo) {
$q->whereBetween('payment_date', [$dateFrom, $dateTo]);
});
}
if (!empty($filters['projects'])) {
$query->whereHas('paymentDistributions', function ($q) use ($filters) {
$q->whereIn('project_id', $filters['projects']);
});
}
if (!empty($filters['accounts'])) {
$query->whereHas('paymentDistributions.payment', function ($q) use ($filters) {
$q->whereIn('account_id', $filters['accounts']);
});
}
if (!empty($filters['payments_made'])) {
$query->whereHas('paymentDistributions.payment', function ($q) use ($filters) {
$q->whereIn('status', $filters['payments_made']);
});
}
if (!empty($filters['cash'])) {
$query->whereHas('paymentDistributions.payment', function ($q) use ($filters) {
$q->whereIn('payment_type', $filters['cash']);
});
}
};
$query->with(['articles' => $articlesCallback]);
$counterpartyIds = collect();
$paymentsIds = collect();
$articleGroups = $query->first();
$articleGroups->articles->each(function ($article) use (&$counterpartyIds, &$paymentsIds) {
$uniqueCounterparties = $article->paymentDistributions
->pluck('payment.contragent')
->unique('id')
->values();
$counterpartyIds = $counterpartyIds->concat($uniqueCounterparties->pluck('id'));
$paymentsIds = $paymentsIds->concat($article->paymentDistributions->pluck('payment_id'));
});
$counterparties = Counterparty::query()
->whereIn('id', $counterpartyIds)
->with(['payments' => function ($query) use ($paymentsIds) {
$query->whereIn('id', $paymentsIds)
->with('distributions.project');
}])
->get();
$articleGroups->setRelation('counterparties', $counterparties);
return $articleGroups;
}
public function getOtherDataShow($modelId, $year, $quarter, $type, $filters)
{
$quarters = [
1 => [1, 2, 3],
2 => [4, 5, 6],
3 => [7, 8, 9],
4 => [10, 11, 12],
];
$months = $quarters[$quarter];
$baseQuery = function ($query, bool $forcePaymentDate = false) use ($year, $months) {
$query->where(function ($q) use ($year, $months, $forcePaymentDate) {
if ($forcePaymentDate) {
$q->whereYear('payment_date', $year)
->whereRaw(
'EXTRACT(MONTH FROM payment_date) IN (' .
implode(',', array_map('intval', $months)) . ')'
);
return;
}
$q->where(function ($q) use ($year, $months) {
$q->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->whereNotNull('actual_date')
->whereYear('actual_date', $year)
->whereRaw('EXTRACT(MONTH FROM actual_date) IN (' . implode(',', array_map('intval', $months)) . ')');
})
->orWhere(function ($q) use ($year, $months) {
$q->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
})
->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 ($year, $months, $modelId, $filters) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now();
$query->where(function ($q) use ($dateFrom, $dateTo) {
$q->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']);
}
$query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId])
->where(function ($q) use ($year, $months) {
$q->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
})
->with('contragent');
}])
->whereHas('payment', function ($query) use ($year, $months, $modelId, $filters) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now();
$query->where(function ($q) use ($dateFrom, $dateTo) {
$q->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']);
}
$query->where(['payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value, 'model_id' => $modelId])
->where(function ($q) use ($year, $months) {
$q->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
});
break;
case 'commission':
$query->where('comission', '!=', null)
->with(['payment' => function ($query) use ($baseQuery, $year, $months, $modelId, $filters) {
$query->where('model_id', $modelId)
->where(function ($q) use ($year, $months) {
$q->where(function ($qMoving) use ($year, $months) {
$qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->where(function ($qPayment) use ($year, $months) {
$qPayment->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
})->orWhere(function ($qOther) use ($year, $months) {
$qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
})
->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, true);
}])
->whereHas('payment', function ($query) use ($baseQuery, $year, $months, $modelId, $filters) {
$query->where('model_id', $modelId)
->where(function ($q) use ($year, $months) {
$q->where(function ($qMoving) use ($year, $months) {
$qMoving->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->where(function ($qPayment) use ($year, $months) {
$qPayment->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
})->orWhere(function ($qOther) use ($year, $months) {
$qOther->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->whereYear('payment_date', $year)
->whereRaw('EXTRACT(MONTH FROM payment_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
});
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, true);
});
break;
case 'cash':
$query->where('cashbox', '!=', null)
->with(['payment' => function ($query) use ($baseQuery, $modelId, $year, $months, $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->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, true);
}])
->whereHas('payment', function ($query) use ($baseQuery, $modelId, $year, $months, $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->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, true);
});
break;
case 'cash-credit':
$query->with(['payment' => function ($query) use ($baseQuery, $modelId, $year, $months, $filters) {
$query->where(function ($q) use ($modelId, $year, $months) {
$q->where([
'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value,
'model_id' => $modelId
])->orWhere(function ($q2) use ($modelId) {
$q2->where([
'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value,
'model_id' => $modelId,
'status' => PaymentStatusEnum::STATUS_RECEIVED->value]);
})->whereNotNull('actual_date')
->whereYear('actual_date', $year)
->whereRaw('EXTRACT(MONTH FROM actual_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
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, $months, $filters) {
$query->where(function ($q) use ($modelId, $year, $months) {
$q->where([
'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value,
'model_id' => $modelId
])
->orWhere(function ($q2) use ($modelId, $year, $months) {
$q2->where([
'payment_type' => PaymentTypeEnum::PAYMENT_TYPE_MOVING->value,
'model_id' => $modelId,
'status' => PaymentStatusEnum::STATUS_RECEIVED->value])
->whereNotNull('actual_date')
->whereYear('actual_date', $year)
->whereRaw('EXTRACT(MONTH FROM actual_date) IN (' . implode(',', array_map('intval', $months)) . ')');
});
});
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = !empty($filters['date_to']) ? $filters['date_to'] : Carbon::now();
$query->where(function ($q) use ($dateFrom, $dateTo) {
$q->where(function ($qActual) use ($dateFrom, $dateTo) {
$qActual->whereNotNull('actual_date')
->whereBetween('actual_date', [$dateFrom, $dateTo]);
})->orWhere(function ($qPayment) use ($dateFrom, $dateTo) {
$qPayment->whereNull('actual_date')
->whereBetween('payment_date', [$dateFrom, $dateTo]);
});
});
}
if (!empty($filters['projects'])) {
$query->whereHas('distributions', function ($query) use ($filters) {
$query->whereIn('project_id', $filters['projects']);
})->with(['distributions' => function ($query) use ($filters) {
$query->whereIn('project_id', $filters['projects']);
}]);
}
if (!empty($filters['accounts'])) {
$query->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$query->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$query->whereIn('payment_type', $filters['cash']);
}
$baseQuery($query);
});
break;
default:
break;
}
if (!empty($filters['accounts'])) {
$query->whereHas('payment', function ($query) use ($filters) {
$query->whereIn('account_id', $filters['accounts']);
});
}
return $query->get();
}
public function 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 sortToQuarterOtherDataDebit($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();
$quarterlyCollection = [];
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));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [
'total_cash' => 0,
'total_commission' => 0,
'total_moving' => 0
],
2 => [
'total_cash' => 0,
'total_commission' => 0,
'total_moving' => 0
],
3 => [
'total_cash' => 0,
'total_commission' => 0,
'total_moving' => 0
],
4 => [
'total_cash' => 0,
'total_commission' => 0,
'total_moving' => 0
]
];
}
$quarterlyCollection[$year][$quarter]['total_commission']+= $distribution->comission;
if ($distribution->payment->payment_type === PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) {
$quarterlyCollection[$year][$quarter]['total_cash']+= $distribution->amount;
if (!is_null($distribution->cashbox)) {
$quarterlyCollection[$year][$quarter]['total_moving']+= $distribution->cashbox;
}
}
}
}
}
if ($check) {
foreach ($quarterlyCollection as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if (($items['total_cash'] == 0) && ($items['total_commission'] == 0) && ($items['total_moving'] == 0)) {
unset($quarterlyCollection[$year][$quarter]);
}
}
if (empty($quarterlyCollection[$year])) {
unset($quarterlyCollection[$year]);
}
}
}
return $quarterlyCollection;
}
public function sortToQuarterTotalCash($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 = $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['payments_made'])) {
$query->whereHas('payment', function ($query) use ($filters) {
$query->whereIn('status', $filters['payments_made']);
});
}
if (!empty($filters['cash'])) {
$query->whereHas('payment', function ($query) use ($filters) {
$query->whereIn('payment_type', $filters['cash']);
});
}
} 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();
$quarterlyCollection = [];
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));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [
'total_cash' => 0,
],
2 => [
'total_cash' => 0,
],
3 => [
'total_cash' => 0,
],
4 => [
'total_cash' => 0,
]
];
}
$quarterlyCollection[$year][$quarter]['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));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [
'total_cash' => 0,
],
2 => [
'total_cash' => 0,
],
3 => [
'total_cash' => 0,
],
4 => [
'total_cash' => 0,
]
];
}
// Используем cashbox для перемещений
if (isset($distribution->cashbox)) {
$quarterlyCollection[$year][$quarter]['total_cash'] += $distribution->cashbox;
}
}
}
if ($check) {
foreach ($quarterlyCollection as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if ($items['total_cash'] == 0) {
unset($quarterlyCollection[$year][$quarter]);
}
}
if (empty($quarterlyCollection[$year])) {
unset($quarterlyCollection[$year]);
}
}
}
return $quarterlyCollection;
}
protected function sortToQuarter($paymentDistributions, $credit, $filter)
{
$quarterlyCollection = [];
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));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [],
2 => [],
3 => [],
4 => []
];
}
$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 ($quarterlyCollection[$year][$quarter] 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) {
$quarterlyCollection[$year][$quarter][] = new CashFlowCreditToMonthResource($distribution);
} else {
$quarterlyCollection[$year][$quarter][] = new CashFlowDebitToMonthResource($distribution);
}
}
}
}
}
}
if ($filter) {
foreach ($quarterlyCollection as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if (empty($items)) {
unset($quarterlyCollection[$year][$quarter]);
}
}
if (empty($quarterlyCollection[$year])) {
unset($quarterlyCollection[$year]);
}
}
}
return $quarterlyCollection;
}
private function getQuarter($date)
{
$month = date('n', strtotime($date));
return ceil($month / 3);
}
public function sumTotalAmount($paymentDistributions)
{
$total = 0;
foreach ($paymentDistributions as $article) {
foreach ($article->paymentDistributions as $distribution) {
if ($distribution->payment == null) {
continue;
}
if (($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_MOVING->value) &&
($distribution->payment->payment_type != PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value)) {
$amount = (float)$distribution->amount;
$total += $amount;
}
}
}
return $total;
}
public function getIncomeAndExpensesToQuarterShow($modelId, $type, $year, $quarter, array $filters = [])
{
$query = PaymentDistribution::query();
$quarters = [
1 => [1, 2, 3],
2 => [4, 5, 6],
3 => [7, 8, 9],
4 => [10, 11, 12],
];
$months = $quarters[$quarter];
$statuses = $filters['payments_made'] ?? [PaymentStatusEnum::STATUS_RECEIVED->value];
$query->whereHas('payment', function ($query) use ($year, $months, $statuses) {
$query->whereYear('payment_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM payment_date)'), $months)
->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 getCashIncomeToQuarterShow($modelId, $year, $quarter)
{
$quarters = [
1 => [1, 2, 3],
2 => [4, 5, 6],
3 => [7, 8, 9],
4 => [10, 11, 12],
];
$months = $quarters[$quarter];
$query = PaymentDistribution::query()
->whereHas('payment', function ($query) use ($modelId, $year, $months) {
$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, $months) {
$q->where(function ($q) use ($year, $months) {
$q->whereNotNull('actual_date')
->whereYear('actual_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM actual_date)'), $months);
});
$q->orWhere(function ($q) use ($year, $months) {
$q->whereNull('actual_date')
->whereYear('payment_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM payment_date)'), $months);
});
});
})
->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 getReceptionIncomeToQuarterShow($modelId, $year, $quarter, $statuses = [])
{
$quarters = [
1 => [1, 2, 3],
2 => [4, 5, 6],
3 => [7, 8, 9],
4 => [10, 11, 12],
];
$months = $quarters[$quarter];
$query = PaymentDistribution::query()
->whereHas('payment', function ($query) use ($modelId, $year, $months, $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, $months) {
$q->where(function ($q) use ($year, $months) {
$q->whereNotNull('actual_date')
->whereYear('actual_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM actual_date)'), $months);
});
$q->orWhere(function ($q) use ($year, $months) {
$q->whereNull('actual_date')
->whereYear('payment_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM payment_date)'), $months);
});
});
})
->with([
'payment.contragent',
'article',
]);
$collection = $query->get();
$collection->each(function ($distribution) {
$distribution->amount = $distribution->cashbox ?? $distribution->amount;
});
return $collection;
}
public function getUndistributedIncomeShowByQuarter($modelId, $year, $quarter, $paymentsMade)
{
$quarters = [
1 => [1, 2, 3],
2 => [4, 5, 6],
3 => [7, 8, 9],
4 => [10, 11, 12],
];
$months = $quarters[$quarter];
$query = PaymentDistribution::query()
->whereHas('payment', function ($query) use ($modelId, $year, $months, $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, $months) {
$q->whereYear('payment_date', $year)
->whereIn(DB::raw('EXTRACT(MONTH FROM payment_date)'), $months);
});
})
->with([
'payment.contragent',
'article',
]);
return $query->get();
}
protected function sortNotDistributedPaymentsToQuarter($paymentDistributions, $credit, $filter)
{
$quarterlyCollection = [];
foreach ($paymentDistributions as $distribution) {
if (!isset($distribution->payment->payment_date)) {
continue;
}
$paymentDate = $distribution->payment->payment_date;
$year = date('Y', strtotime($paymentDate));
$quarter = $this->getQuarter($paymentDate);
if (!isset($quarterlyCollection[$year])) {
$quarterlyCollection[$year] = [
1 => [],
2 => [],
3 => [],
4 => []
];
}
$amount = $credit
? $distribution->amount
: $distribution->amount;
$quarterlyCollection[$year][$quarter]['total_amount'] = ($quarterlyCollection[$year][$quarter]['total_amount'] ?? 0) + $amount;
}
if ($filter) {
foreach ($quarterlyCollection as $year => $quarters) {
foreach ($quarters as $quarter => $items) {
if (empty($items)) {
unset($quarterlyCollection[$year][$quarter]);
}
}
if (empty($quarterlyCollection[$year])) {
unset($quarterlyCollection[$year]);
}
}
}
return $quarterlyCollection;
}
private function mergeDistributedAndNotDistributedByQuarter(array $totalAmount, array $notDistributedPayments): array
{
foreach ($notDistributedPayments as $year => $quarters) {
foreach ($quarters as $quarter => $data) {
if ($quarter === 'total') continue;
$amount = $data['total_amount'] ?? 0;
if (!isset($totalAmount[$year][$quarter])) {
$totalAmount[$year][$quarter] = 0;
}
$totalAmount[$year][$quarter] += $amount;
}
}
// пересчёт total по годам
foreach ($totalAmount as $year => $quarters) {
$totalAmount[$year]['total'] = array_sum(array_filter($quarters, fn($k) => $k !== 'total', ARRAY_FILTER_USE_KEY));
}
return $totalAmount;
}
}