ultimatepos/Modules/Accounting/Services/DepreciationService.php

93 lines
3.1 KiB
PHP

<?php
namespace Modules\Accounting\Services;
use Modules\Accounting\Domain\FinancialPostingRequest;
use Modules\Accounting\Entities\AccountingDepreciationRun;
class DepreciationService
{
public function __construct(protected FinancialPostingService $postingService) {}
public function createRun(array $data, int $businessId, int $userId): AccountingDepreciationRun
{
return AccountingDepreciationRun::create(array_merge($data, [
'business_id' => $businessId,
'created_by' => $userId,
'status' => 'draft',
]));
}
public function postRun(AccountingDepreciationRun $run, int $userId): AccountingDepreciationRun
{
if ($run->status === 'posted') {
return $run;
}
if (empty($run->expense_account_id) || empty($run->accumulated_account_id)) {
throw new \RuntimeException('Depreciation accounts are required.');
}
$amount = (float) $run->depreciation_amount;
$mapping = $this->postingService->post(new FinancialPostingRequest(
businessId: $run->business_id,
userId: $userId,
sourceType: 'depreciation',
sourceId: $run->id,
note: 'Depreciation '.$run->period_label,
lines: [
['accounting_account_id' => $run->expense_account_id, 'amount' => $amount, 'type' => 'debit'],
['accounting_account_id' => $run->accumulated_account_id, 'amount' => $amount, 'type' => 'credit'],
],
operationDate: $run->period_date,
));
$run->journal_mapping_id = $mapping?->id;
$run->status = 'posted';
$run->save();
return $run;
}
public function batchFromAssets(int $businessId, int $userId, string $periodDate, int $expenseAccountId, int $accumulatedAccountId): array
{
if (! class_exists(\Modules\AssetManagement\Entities\Asset::class)) {
return ['created' => 0, 'posted' => 0];
}
$periodLabel = date('Y-m', strtotime($periodDate));
$assets = \Modules\AssetManagement\Entities\Asset::where('business_id', $businessId)
->where('depreciation', '>', 0)
->get();
$created = 0;
$posted = 0;
foreach ($assets as $asset) {
$exists = AccountingDepreciationRun::where('business_id', $businessId)
->where('asset_id', $asset->id)
->where('period_label', $periodLabel)
->exists();
if ($exists) {
continue;
}
$run = $this->createRun([
'asset_id' => $asset->id,
'period_label' => $periodLabel,
'period_date' => $periodDate,
'depreciation_amount' => (float) $asset->depreciation,
'expense_account_id' => $expenseAccountId,
'accumulated_account_id' => $accumulatedAccountId,
], $businessId, $userId);
$created++;
$this->postRun($run, $userId);
$posted++;
}
return ['created' => $created, 'posted' => $posted];
}
}