$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]; } }