status !== 'completed' || $workOrder->accounting_journal_mapping_id) { return; } if (! class_exists(AccountingAccTransMapping::class)) { return; } if (! $this->maintenanceUtil->isAccountingEnabled($businessId)) { return; } $settings = $this->maintenanceUtil->getMaintenanceSettings($businessId); if (empty($settings['auto_post_journal'])) { return; } $expenseAccountId = $settings['expense_account_id'] ?? null; $paymentAccountId = $settings['payment_account_id'] ?? null; if (empty($expenseAccountId) || empty($paymentAccountId)) { throw new MaintenanceAccountingException('Maintenance accounting accounts are not configured.'); } $amount = (float) $workOrder->cost; if ($amount <= 0) { return; } DB::transaction(function () use ($workOrder, $businessId, $userId, $expenseAccountId, $paymentAccountId, $amount) { if (class_exists(\Modules\Accounting\Services\FinancialPostingService::class)) { $postingService = app(\Modules\Accounting\Services\FinancialPostingService::class); $entityResolution = app(\Modules\Accounting\Services\HoldingEntityResolutionService::class); $locationId = optional($workOrder->equipment)->branch_id ?? null; $holdingEntityId = $entityResolution->resolveFromLocation($businessId, $locationId ? (int) $locationId : null); $request = new \Modules\Accounting\Domain\FinancialPostingRequest( businessId: $businessId, userId: $userId, sourceType: 'maintenance_work_order', sourceId: $workOrder->id, note: 'هزینه دستور کار نگهداری: '.$workOrder->work_order_number, lines: [ ['accounting_account_id' => $expenseAccountId, 'amount' => $amount, 'type' => 'debit', 'holding_entity_id' => $holdingEntityId], ['accounting_account_id' => $paymentAccountId, 'amount' => $amount, 'type' => 'credit', 'holding_entity_id' => $holdingEntityId], ], operationDate: ($workOrder->completed_at ?? now())->toDateTimeString(), holdingEntityId: $holdingEntityId, ); $mapping = $postingService->post($request); if (! $mapping?->id) { throw new MaintenanceAccountingException('Maintenance journal posting returned no mapping.'); } $workOrder->update(['accounting_journal_mapping_id' => $mapping->id]); return; } $mapping = new AccountingAccTransMapping(); $mapping->business_id = $businessId; $mapping->ref_no = $this->generateRefNo($businessId); $mapping->note = 'هزینه دستور کار نگهداری: '.$workOrder->work_order_number; $mapping->type = 'journal_entry'; $mapping->created_by = $userId; $mapping->operation_date = $workOrder->completed_at ?? now(); $mapping->save(); $operationDate = $mapping->operation_date; AccountingAccountsTransaction::create([ 'accounting_account_id' => $expenseAccountId, 'amount' => $amount, 'type' => 'debit', 'sub_type' => 'journal_entry', 'created_by' => $userId, 'operation_date' => $operationDate, 'acc_trans_mapping_id' => $mapping->id, ]); AccountingAccountsTransaction::create([ 'accounting_account_id' => $paymentAccountId, 'amount' => $amount, 'type' => 'credit', 'sub_type' => 'journal_entry', 'created_by' => $userId, 'operation_date' => $operationDate, 'acc_trans_mapping_id' => $mapping->id, ]); $workOrder->update(['accounting_journal_mapping_id' => $mapping->id]); }); } protected function generateRefNo(int $businessId): string { $accountingUtil = class_exists(\Modules\Accounting\Utils\AccountingUtil::class) ? app(\Modules\Accounting\Utils\AccountingUtil::class) : null; $settings = $accountingUtil ? $accountingUtil->getAccountingSettings($businessId) : []; $refCount = $this->util->setAndGetReferenceCount('journal_entry'); $prefix = $settings['journal_entry_prefix'] ?? 'MJ-'; return $this->util->generateReferenceNumber('journal_entry', $refCount, $businessId, $prefix); } }