ultimatepos/Modules/Accounting/Services/OpeningBalanceService.php

58 lines
2.0 KiB
PHP

<?php
namespace Modules\Accounting\Services;
use Illuminate\Support\Facades\DB;
use Modules\Accounting\Domain\FinancialPostingRequest;
use Modules\Accounting\Entities\AccountingAccount;
class OpeningBalanceService
{
public function __construct(protected FinancialPostingService $postingService) {}
public function post(int $businessId, int $userId, string $operationDate, array $lines, ?string $note = null)
{
$journalLines = [];
foreach ($lines as $line) {
if (empty($line['accounting_account_id']) || empty($line['amount']) || empty($line['type'])) {
continue;
}
$journalLines[] = [
'accounting_account_id' => (int) $line['accounting_account_id'],
'amount' => (float) $line['amount'],
'type' => $line['type'],
'sub_type' => 'opening_balance',
];
}
if (count($journalLines) < 2) {
throw new \InvalidArgumentException('Opening balance requires at least two lines.');
}
return $this->postingService->post(new FinancialPostingRequest(
businessId: $businessId,
userId: $userId,
sourceType: 'opening_balance',
sourceId: $operationDate,
note: $note ?? 'Opening balance entry',
lines: $journalLines,
operationDate: $operationDate,
mappingType: 'journal_entry',
), allowDuplicate: false);
}
public function accountsWithoutActivity(int $businessId): array
{
return AccountingAccount::where('business_id', $businessId)
->where('status', 'active')
->whereNotExists(function ($q) {
$q->select(DB::raw(1))
->from('accounting_accounts_transactions as aat')
->whereColumn('aat.accounting_account_id', 'accounting_accounts.id');
})
->orderBy('name')
->pluck('name', 'id')
->all();
}
}