<?php
namespace App\Repositories\CashFlowIndex;
use App\Domain\Payment\Enums\PaymentStatusEnum;
use App\Domain\Payment\Enums\PaymentTypeEnum;
use App\Models\Article;
use App\Models\Payment;
use App\Models\PaymentDistribution;
use App\Repositories\CashFlowIndex\Interfaces\PaymentDistributionsRepositoryInterface;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
class PaymentDistributionsRepository implements PaymentDistributionsRepositoryInterface
{
public function getPaymentDistributions($modelId, $filters, $typeEnum): Collection
{
$query = Article::query();
$query->where('model_id', $modelId);
$query->where('article_type', $typeEnum)
->where('id', '!=', 1);
$filters = array_filter($filters, function ($value) {
return $value !== null;
});
if (empty($filters)) {
$query->with(['paymentDistributions.payment' => function ($paymentQuery) {
$paymentQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value)
->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value)
->with('account');
}, 'group'])
->whereHas('paymentDistributions.payment', function ($paymentQuery) {
$paymentQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value)
->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value);
});
} else {
if (!empty($filters)) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to'];
$query->with('paymentDistributions.payment', function ($subQuery) use ($dateFrom, $dateTo) {
$subQuery->whereBetween('payment_date', [$dateFrom, $dateTo]);
});
}
if (!empty($filters['projects'])) {
$query->with('paymentDistributions', function ($subQuery) use ($filters) {
$subQuery->whereIn('project_id', $filters['projects']);
});
}
if (!empty($filters['accounts'])) {
$query->with('paymentDistributions.payment', function ($subQuery) use ($filters) {
$subQuery->whereIn('account_id', $filters['accounts']);
});
}
if (!empty($filters['payments_made'])) {
$query->with('paymentDistributions.payment', function ($subQuery) use ($filters) {
$subQuery->whereIn('status', $filters['payments_made']);
});
}
if (!empty($filters['cash'])) {
$query->with('paymentDistributions.payment', function ($subQuery) use ($filters) {
$subQuery->whereIn('payment_type', $filters['cash']);
});
}
$query->with([
'paymentDistributions' => function ($paymentDistributionQuery) use ($filters) {
if (!empty($filters['projects'])) {
$paymentDistributionQuery->whereIn('project_id', $filters['projects']);
}
$paymentDistributionQuery->whereHas('payment', function ($paymentFilterQuery) use ($filters) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to'];
$paymentFilterQuery->whereBetween('payment_date', [$dateFrom, $dateTo]);
}
if (!empty($filters['accounts'])) {
$paymentFilterQuery->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$paymentFilterQuery->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$paymentFilterQuery->whereIn('payment_type', $filters['cash']);
}
$paymentFilterQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value)
->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value);
});
$paymentDistributionQuery->with([
'payment.account',
'payment' => function ($paymentFilterQuery) use ($filters) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = empty($filters['date_to']) ? Carbon::now() : $filters['date_to'];
$paymentFilterQuery->whereBetween('payment_date', [$dateFrom, $dateTo]);
}
if (!empty($filters['accounts'])) {
$paymentFilterQuery->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$paymentFilterQuery->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$paymentFilterQuery->whereIn('payment_type', $filters['cash']);
}
$paymentFilterQuery->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION->value)
->where('payment_type', '!=', PaymentTypeEnum::PAYMENT_TYPE_MOVING->value);
}
]);
}
]);
}
}
return $query->orderBy('sort', 'ASC')->get();
}
public function getPaymentDistributionsProject($modelId, $filters, $typeEnum): Collection
{
$query = Article::query()->where('id', '!=', 1);
$query->where('model_id', $modelId);
$query->where('article_type', $typeEnum);
$filters = array_filter($filters, function ($value) {
return $value !== null;
});
if (empty($filters)) {
$query->with(['paymentDistributions.payment.account', 'paymentDistributions.project']);
} else {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = $filters['date_to'] ?? now();
$query->with('paymentDistributions.payment', fn($q) => $q->whereBetween('payment_date', [$dateFrom, $dateTo]));
}
if (!empty($filters['projects'])) {
$query->with('paymentDistributions', fn($q) => $q->whereIn('project_id', $filters['projects']));
}
if (!empty($filters['accounts'])) {
$query->with('paymentDistributions.payment', fn($q) => $q->whereIn('account_id', $filters['accounts']));
}
if (!empty($filters['payments_made'])) {
$query->with('paymentDistributions.payment', fn($q) => $q->whereIn('status', $filters['payments_made']));
}
if (!empty($filters['cash'])) {
$query->with('paymentDistributions.payment', fn($q) => $q->whereIn('payment_type', $filters['cash']));
}
$query->with(['paymentDistributions' => function ($dist) use ($filters) {
if (!empty($filters['projects'])) {
$dist->whereIn('project_id', $filters['projects']);
}
$dist->whereHas('payment', function ($pay) use ($filters) {
if (!empty($filters['date_from'])) {
$pay->whereBetween('payment_date', [
$filters['date_from'],
$filters['date_to'] ?? now()
]);
}
if (!empty($filters['accounts'])) {
$pay->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$pay->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$pay->whereIn('payment_type', $filters['cash']);
}
});
$dist->with([
'payment.account',
'payment' => function ($pay) use ($filters) {
if (!empty($filters['date_from'])) {
$pay->whereBetween('payment_date', [
$filters['date_from'],
$filters['date_to'] ?? now()
]);
}
if (!empty($filters['accounts'])) {
$pay->whereIn('account_id', $filters['accounts']);
}
if (!empty($filters['payments_made'])) {
$pay->whereIn('status', $filters['payments_made']);
}
if (!empty($filters['cash'])) {
$pay->whereIn('payment_type', $filters['cash']);
}
},
'project'
]);
}]);
}
return $query->orderBy('sort', 'ASC')->get();
}
public function getNotDistributionsPayment(int $modelID, $filters, bool $credit): Collection
{
$query = PaymentDistribution::query()->with('payment');
$query->whereNull('article_id');
$query->whereHas('payment', function ($q) use ($modelID, $credit) {
$q->where('model_id', $modelID);
if ($credit) {
$q->where('payment_type', PaymentTypeEnum::PAYMENT_TYPE_RECEPTION_FROM_1C->value);
} else {
$q->whereIn('payment_type', [
PaymentTypeEnum::PAYMENT_TYPE_PAYMENT->value,
PaymentTypeEnum::PAYMENT_TYPE_ISSUEANCE->value
]);
}
});
if (!empty($filters)) {
$query->whereHas('payment', function ($q) use ($filters) {
if (!empty($filters['date_from'])) {
$dateFrom = $filters['date_from'];
$dateTo = $filters['date_to'] ?? now();
$q->whereBetween('payment_date', [$dateFrom, $dateTo]);
}
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']);
}
}
return $query->get();
}
public function getNotDistributionsPaymentProject($modelID, $filters, $credit): Collection
{
$query = $this->getNotDistributionsPayment($modelID, $filters, $credit);
if (!empty($filters['projects'])) {
$query = $query->filter(function ($payment) use ($filters) {
return in_array($payment->project_id, $filters['projects']);
});
}
return $query;
}
}