ultimatepos/Modules/Accounting/Services/InstallmentBridgeService.php

88 lines
3.1 KiB
PHP

<?php
namespace Modules\Accounting\Services;
use App\Transaction;
use Carbon\Carbon;
use Modules\Accounting\Entities\AccountingInstallmentPlan;
class InstallmentBridgeService
{
public function __construct(protected InstallmentService $installmentService) {}
public function isEligibleForManualInstallment(Transaction $transaction): bool
{
if ($transaction->type !== 'sell' || $transaction->status !== 'final') {
return false;
}
if (! in_array($transaction->payment_status, ['due', 'partial'], true)) {
return false;
}
if (empty($transaction->pay_term_number) || (int) $transaction->pay_term_number < 2) {
return false;
}
return ! $this->getPlanForSell($transaction);
}
public function getPlanForSell(Transaction $transaction): ?AccountingInstallmentPlan
{
return AccountingInstallmentPlan::where('business_id', $transaction->business_id)
->where('transaction_id', $transaction->id)
->first();
}
public function shouldCreateFromSell(Transaction $transaction): bool
{
if (! $this->isEligibleForManualInstallment($transaction)) {
return false;
}
$settings = app(\Modules\Accounting\Utils\AccountingUtil::class)->getAccountingSettings($transaction->business_id);
return ! empty($settings['auto_installment_from_sell']);
}
public function createFromSell(Transaction $transaction, int $userId, ?int $installmentCount = null): ?AccountingInstallmentPlan
{
$count = $installmentCount ?? (int) $transaction->pay_term_number;
if ($count < 2) {
return null;
}
if (AccountingInstallmentPlan::where('business_id', $transaction->business_id)
->where('transaction_id', $transaction->id)->exists()) {
return null;
}
$frequency = 'monthly';
$startDate = Carbon::parse($transaction->transaction_date)->addMonth();
return $this->installmentService->createPlan([
'transaction_id' => $transaction->id,
'contact_id' => $transaction->contact_id,
'principal_amount' => (float) $transaction->final_total,
'installment_count' => $count,
'interest_rate' => 0,
'start_date' => $startDate->toDateString(),
'frequency' => $frequency,
], (int) $transaction->business_id, $userId);
}
public function eligibleSells(int $businessId)
{
return Transaction::where('business_id', $businessId)
->where('type', 'sell')
->where('status', 'final')
->whereIn('payment_status', ['due', 'partial'])
->whereNotNull('pay_term_number')
->where('pay_term_number', '>=', 2)
->whereNotIn('id', AccountingInstallmentPlan::where('business_id', $businessId)->pluck('transaction_id'))
->orderByDesc('id')
->limit(50)
->get(['id', 'invoice_no', 'contact_id', 'final_total', 'pay_term_number', 'transaction_date', 'payment_status']);
}
}