93 lines
3.1 KiB
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];
|
|
}
|
|
}
|