133 lines
5.4 KiB
PHP
133 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace Modules\Maintenance\Services;
|
|
|
|
use App\Business;
|
|
use App\Utils\Util;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Modules\Accounting\Entities\AccountingAccountsTransaction;
|
|
use Modules\Accounting\Entities\AccountingAccTransMapping;
|
|
use Modules\Maintenance\Exceptions\MaintenanceAccountingException;
|
|
use Modules\Maintenance\Models\WorkOrder;
|
|
use Modules\Maintenance\Utils\MaintenanceUtil;
|
|
|
|
class MaintenanceAccountingService
|
|
{
|
|
public function __construct(
|
|
protected MaintenanceUtil $maintenanceUtil,
|
|
protected Util $util
|
|
) {}
|
|
|
|
public function postWorkOrderIfCompleted(WorkOrder $workOrder, int $businessId, int $userId): void
|
|
{
|
|
if ($workOrder->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);
|
|
}
|
|
}
|