updates to UI and add archiving option
This commit is contained in:
@@ -215,6 +215,16 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||
$rawAssoc = $this->buildRowAssoc($row, $header);
|
||||
[$recordType, $mapped] = $this->applyMappings($rawAssoc, $mappings);
|
||||
|
||||
// Determine row-level reactivation intent: precedence row > import > template
|
||||
$rowReactivate = false;
|
||||
$rawReactivateVal = $rawAssoc['reactivate'] ?? null; // direct column named 'reactivate'
|
||||
if (! is_null($rawReactivateVal)) {
|
||||
$rowReactivate = filter_var($rawReactivateVal, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false;
|
||||
}
|
||||
$importReactivate = (bool) ($import->reactivate ?? false);
|
||||
$templateReactivate = (bool) (optional($import->template)->reactivate ?? false);
|
||||
$reactivateMode = $rowReactivate || $importReactivate || $templateReactivate;
|
||||
|
||||
// Do not auto-derive or fallback values; only use explicitly mapped fields
|
||||
|
||||
$rawSha1 = sha1(json_encode($rawAssoc));
|
||||
@@ -230,6 +240,7 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||
|
||||
// Contracts
|
||||
$contractResult = null;
|
||||
$reactivatedThisRow = false;
|
||||
if (isset($mapped['contract'])) {
|
||||
// In payments-import with contract_key_mode=reference, treat contract.reference as a keyref only
|
||||
if ($paymentsImport && $contractKeyMode === 'reference') {
|
||||
@@ -248,6 +259,29 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||
$found = $q->first();
|
||||
if ($found) {
|
||||
$contractResult = ['action' => 'resolved', 'contract' => $found];
|
||||
// Reactivation branch for resolved existing contract
|
||||
if ($reactivateMode && ($found->active == 0 || $found->deleted_at)) {
|
||||
$reactivationApplied = $this->attemptContractReactivation($found, $user);
|
||||
if ($reactivationApplied['reactivated']) {
|
||||
$reactivatedThisRow = true;
|
||||
$imported++;
|
||||
$importRow->update([
|
||||
'status' => 'imported',
|
||||
'entity_type' => Contract::class,
|
||||
'entity_id' => $found->id,
|
||||
]);
|
||||
ImportEvent::create([
|
||||
'import_id' => $import->id,
|
||||
'user_id' => $user?->getAuthIdentifier(),
|
||||
'import_row_id' => $importRow->id,
|
||||
'event' => 'contract_reactivated',
|
||||
'level' => 'info',
|
||||
'message' => 'Contract reactivated via import.',
|
||||
'context' => ['contract_id' => $found->id],
|
||||
]);
|
||||
// Do NOT continue; allow postContractActions + account processing below.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$contractResult = null; // let requireContract logic flag invalid later
|
||||
}
|
||||
@@ -256,6 +290,31 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||
}
|
||||
} else {
|
||||
$contractResult = $this->upsertContractChain($import, $mapped, $mappings);
|
||||
// If contract was resolved/updated/inserted and reactivation requested but not needed (already active), we just continue normal flow.
|
||||
if ($reactivateMode && $contractResult && isset($contractResult['contract']) && $contractResult['contract'] instanceof Contract) {
|
||||
$found = $contractResult['contract'];
|
||||
if ($found->active == 0 || $found->deleted_at) {
|
||||
$reactivationApplied = $this->attemptContractReactivation($found, $user);
|
||||
if ($reactivationApplied['reactivated']) {
|
||||
$reactivatedThisRow = true;
|
||||
$importRow->update([
|
||||
'status' => 'imported',
|
||||
'entity_type' => Contract::class,
|
||||
'entity_id' => $found->id,
|
||||
]);
|
||||
ImportEvent::create([
|
||||
'import_id' => $import->id,
|
||||
'user_id' => $user?->getAuthIdentifier(),
|
||||
'import_row_id' => $importRow->id,
|
||||
'event' => 'contract_reactivated',
|
||||
'level' => 'info',
|
||||
'message' => 'Contract reactivated via import (post-upsert).',
|
||||
'context' => ['contract_id' => $found->id],
|
||||
]);
|
||||
// Do not continue; allow post actions + account handling.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($contractResult['action'] === 'skipped') {
|
||||
// Even if no contract fields were updated, we may still need to apply template meta
|
||||
@@ -315,17 +374,19 @@ public function process(Import $import, ?Authenticatable $user = null): array
|
||||
]);
|
||||
|
||||
// Post-contract actions from template/import meta
|
||||
try {
|
||||
$this->postContractActions($import, $contractResult['contract']);
|
||||
} catch (\Throwable $e) {
|
||||
ImportEvent::create([
|
||||
'import_id' => $import->id,
|
||||
'user_id' => $user?->getAuthIdentifier(),
|
||||
'import_row_id' => $importRow->id,
|
||||
'event' => 'post_contract_action_failed',
|
||||
'level' => 'warning',
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
if (! $reactivateMode || $reactivatedThisRow) { // run post actions also for reactivated contracts
|
||||
try {
|
||||
$this->postContractActions($import, $contractResult['contract']);
|
||||
} catch (\Throwable $e) {
|
||||
ImportEvent::create([
|
||||
'import_id' => $import->id,
|
||||
'user_id' => $user?->getAuthIdentifier(),
|
||||
'import_row_id' => $importRow->id,
|
||||
'event' => 'post_contract_action_failed',
|
||||
'level' => 'warning',
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$invalid++;
|
||||
@@ -1073,6 +1134,7 @@ private function upsertAccount(Import $import, array $mapped, $mappings): array
|
||||
$existing = Account::query()
|
||||
->where('contract_id', $contractId)
|
||||
->where('reference', $reference)
|
||||
->where('active', 1)
|
||||
->first();
|
||||
|
||||
// Build applyable data based on apply_mode
|
||||
@@ -2032,4 +2094,59 @@ private function postContractActions(Import $import, Contract $contract): void
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to reactivate a single archived contract via the latest enabled reactivate ArchiveSetting.
|
||||
* Returns array{reactivated: bool}.
|
||||
*/
|
||||
protected function attemptContractReactivation(Contract $contract, ?Authenticatable $user = null): array
|
||||
{
|
||||
try {
|
||||
// Skip if already active
|
||||
if ($contract->active && ! $contract->deleted_at) {
|
||||
return ['reactivated' => false];
|
||||
}
|
||||
$setting = \App\Models\ArchiveSetting::query()
|
||||
->where('enabled', true)
|
||||
->where('reactivate', true)
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
if (! $setting) {
|
||||
return ['reactivated' => false];
|
||||
}
|
||||
$context = [
|
||||
'contract_id' => $contract->id,
|
||||
'client_case_id' => $contract->client_case_id,
|
||||
];
|
||||
if ($contract->account) {
|
||||
$context['account_id'] = $contract->account->id;
|
||||
}
|
||||
$executor = app(\App\Services\Archiving\ArchiveExecutor::class);
|
||||
$executor->executeSetting($setting, $context, $user?->getAuthIdentifier());
|
||||
// Ensure contract flagged active (safety)
|
||||
$contract->forceFill(['active' => 1, 'deleted_at' => null])->save();
|
||||
|
||||
// Activity from archive setting (if action/decision present) handled inside executor path or we can optionally create here
|
||||
if ($setting->action_id || $setting->decision_id) {
|
||||
try {
|
||||
Activity::create([
|
||||
'due_date' => null,
|
||||
'amount' => null,
|
||||
'note' => 'Ponovna aktivacija pogodba '.$contract->reference,
|
||||
'action_id' => $setting->action_id,
|
||||
'decision_id' => $setting->decision_id,
|
||||
'client_case_id' => $contract->client_case_id,
|
||||
'contract_id' => $contract->id,
|
||||
'user_id' => $user?->getAuthIdentifier(),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
// Non-fatal
|
||||
}
|
||||
}
|
||||
|
||||
return ['reactivated' => true];
|
||||
} catch (\Throwable $e) {
|
||||
return ['reactivated' => false];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user