203 lines
7.5 KiB
PHP
203 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace Modules\Accounting\Services;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Modules\Accounting\Entities\AccountingAccTransMapping;
|
|
use Modules\Accounting\Entities\AccountingCheque;
|
|
use Modules\Accounting\Entities\AccountingInstallmentSchedule;
|
|
|
|
class DeferredDocumentsService
|
|
{
|
|
public function summary(int $businessId): array
|
|
{
|
|
$cheques = $this->pendingChequeCount($businessId);
|
|
$installments = $this->overdueInstallmentCount($businessId);
|
|
$invoices = $this->overdueInvoiceCount($businessId);
|
|
$journals = $this->pendingJournalCount($businessId);
|
|
|
|
return [
|
|
'cheques' => $cheques,
|
|
'installments' => $installments,
|
|
'invoices' => $invoices,
|
|
'journals' => $journals,
|
|
'total' => $cheques + $installments + $invoices + $journals,
|
|
];
|
|
}
|
|
|
|
public function items(int $businessId): array
|
|
{
|
|
$items = [];
|
|
|
|
foreach ($this->pendingCheques($businessId) as $cheque) {
|
|
$items[] = [
|
|
'type' => 'cheque',
|
|
'type_label' => __('accounting::lang.cheques'),
|
|
'reference' => $cheque->cheque_number,
|
|
'party' => $cheque->bank_name ?: '-',
|
|
'amount' => (float) $cheque->amount,
|
|
'due_date' => optional($cheque->due_date)->format('Y-m-d'),
|
|
'status' => $cheque->status,
|
|
'url' => route('accounting.cheques'),
|
|
];
|
|
}
|
|
|
|
foreach ($this->overdueInstallments($businessId) as $row) {
|
|
$outstanding = max(0, (float) $row->amount + (float) ($row->penalty_amount ?? 0) - (float) $row->paid_amount);
|
|
$items[] = [
|
|
'type' => 'installment',
|
|
'type_label' => __('accounting::lang.installments'),
|
|
'reference' => '#'.$row->installment_number,
|
|
'party' => __('accounting::lang.installment_plan').' #'.$row->installment_plan_id,
|
|
'amount' => $outstanding,
|
|
'due_date' => $row->due_date,
|
|
'status' => $row->status,
|
|
'url' => route('accounting.installments'),
|
|
];
|
|
}
|
|
|
|
foreach ($this->overdueInvoices($businessId) as $invoice) {
|
|
$items[] = [
|
|
'type' => 'invoice',
|
|
'type_label' => __('sale.invoice'),
|
|
'reference' => $invoice->invoice_no,
|
|
'party' => $invoice->contact_name ?? '-',
|
|
'amount' => (float) $invoice->total_due,
|
|
'due_date' => $invoice->due_date,
|
|
'status' => $invoice->payment_status,
|
|
'url' => action([\App\Http\Controllers\SellController::class, 'index']),
|
|
];
|
|
}
|
|
|
|
foreach ($this->pendingJournals($businessId) as $journal) {
|
|
$items[] = [
|
|
'type' => 'journal',
|
|
'type_label' => __('accounting::lang.journal_entry'),
|
|
'reference' => $journal->ref_no ?? '#'.$journal->id,
|
|
'party' => $journal->note ?? '-',
|
|
'amount' => null,
|
|
'due_date' => optional($journal->operation_date)->format('Y-m-d'),
|
|
'status' => $journal->approval_status,
|
|
'url' => route('accounting.journalApprovals'),
|
|
];
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
|
|
protected function pendingChequeCount(int $businessId): int
|
|
{
|
|
if (! Schema::hasTable('accounting_cheques')) {
|
|
return 0;
|
|
}
|
|
|
|
return (int) AccountingCheque::where('business_id', $businessId)
|
|
->whereIn('status', ['pending', 'deposited'])
|
|
->where(function ($q) {
|
|
$q->whereNull('due_date')
|
|
->orWhereDate('due_date', '<=', Carbon::today()->toDateString());
|
|
})
|
|
->count();
|
|
}
|
|
|
|
protected function overdueInstallmentCount(int $businessId): int
|
|
{
|
|
if (! Schema::hasTable('accounting_installment_schedule')) {
|
|
return 0;
|
|
}
|
|
|
|
return (int) DB::table('accounting_installment_schedule as s')
|
|
->join('accounting_installment_plans as p', 'p.id', '=', 's.installment_plan_id')
|
|
->where('p.business_id', $businessId)
|
|
->whereIn('s.status', ['overdue', 'pending'])
|
|
->whereDate('s.due_date', '<', Carbon::today()->toDateString())
|
|
->count();
|
|
}
|
|
|
|
protected function overdueInvoiceCount(int $businessId): int
|
|
{
|
|
if (! Schema::hasTable('transactions') || ! Schema::hasColumn('transactions', 'due_date')) {
|
|
return 0;
|
|
}
|
|
|
|
return (int) DB::table('transactions')
|
|
->where('business_id', $businessId)
|
|
->where('type', 'sell')
|
|
->where('status', 'final')
|
|
->whereIn('payment_status', ['due', 'partial'])
|
|
->whereNotNull('due_date')
|
|
->whereDate('due_date', '<', Carbon::today()->toDateString())
|
|
->count();
|
|
}
|
|
|
|
protected function pendingJournalCount(int $businessId): int
|
|
{
|
|
if (! Schema::hasTable('accounting_acc_trans_mappings') || ! Schema::hasColumn('accounting_acc_trans_mappings', 'approval_status')) {
|
|
return 0;
|
|
}
|
|
|
|
return (int) AccountingAccTransMapping::where('business_id', $businessId)
|
|
->where('approval_status', 'pending')
|
|
->count();
|
|
}
|
|
|
|
protected function pendingCheques(int $businessId)
|
|
{
|
|
return AccountingCheque::where('business_id', $businessId)
|
|
->whereIn('status', ['pending', 'deposited'])
|
|
->where(function ($q) {
|
|
$q->whereNull('due_date')
|
|
->orWhereDate('due_date', '<=', Carbon::today()->toDateString());
|
|
})
|
|
->orderBy('due_date')
|
|
->limit(100)
|
|
->get();
|
|
}
|
|
|
|
protected function overdueInstallments(int $businessId)
|
|
{
|
|
return DB::table('accounting_installment_schedule as s')
|
|
->join('accounting_installment_plans as p', 'p.id', '=', 's.installment_plan_id')
|
|
->where('p.business_id', $businessId)
|
|
->whereIn('s.status', ['overdue', 'pending'])
|
|
->whereDate('s.due_date', '<', Carbon::today()->toDateString())
|
|
->select('s.*')
|
|
->orderBy('s.due_date')
|
|
->limit(100)
|
|
->get();
|
|
}
|
|
|
|
protected function overdueInvoices(int $businessId)
|
|
{
|
|
return DB::table('transactions as t')
|
|
->leftJoin('contacts as c', 'c.id', '=', 't.contact_id')
|
|
->where('t.business_id', $businessId)
|
|
->where('t.type', 'sell')
|
|
->where('t.status', 'final')
|
|
->whereIn('t.payment_status', ['due', 'partial'])
|
|
->whereNotNull('t.due_date')
|
|
->whereDate('t.due_date', '<', Carbon::today()->toDateString())
|
|
->select(
|
|
't.invoice_no',
|
|
't.payment_status',
|
|
't.due_date',
|
|
'c.name as contact_name',
|
|
DB::raw('(t.final_total - COALESCE((SELECT SUM(IF(tp.is_return=1,-1*tp.amount,tp.amount)) FROM transaction_payments tp WHERE tp.transaction_id=t.id),0)) as total_due')
|
|
)
|
|
->orderBy('t.due_date')
|
|
->limit(100)
|
|
->get();
|
|
}
|
|
|
|
protected function pendingJournals(int $businessId)
|
|
{
|
|
return AccountingAccTransMapping::where('business_id', $businessId)
|
|
->where('approval_status', 'pending')
|
|
->orderByDesc('id')
|
|
->limit(50)
|
|
->get();
|
|
}
|
|
}
|