fixed import

This commit is contained in:
Simon Pocrnjič
2025-12-28 13:55:09 +01:00
parent 84b75143df
commit 36b63a180d
9 changed files with 548 additions and 34 deletions
@@ -5,6 +5,7 @@
use App\Models\Account;
use App\Models\Import;
use App\Services\Import\BaseEntityHandler;
use App\Services\Import\DecimalNormalizer;
class AccountHandler extends BaseEntityHandler
{
@@ -13,10 +14,38 @@ public function getEntityClass(): string
return Account::class;
}
/**
* Override validate to handle contract_id and reference from context.
* Both contract_id and reference are populated in process() (reference defaults to contract reference).
*/
public function validate(array $mapped): array
{
// Remove contract_id and reference from validation - both will be populated in process()
// Reference defaults to contract.reference if not set (matching v1 behavior)
$rules = $this->entityConfig?->validation_rules ?? [];
unset($rules['contract_id'], $rules['reference']);
if (empty($rules)) {
return ['valid' => true, 'errors' => []];
}
$validator = \Illuminate\Support\Facades\Validator::make($mapped, $rules);
if ($validator->fails()) {
return [
'valid' => false,
'errors' => $validator->errors()->all(),
];
}
return ['valid' => true, 'errors' => []];
}
public function resolve(array $mapped, array $context = []): mixed
{
$reference = $mapped['reference'] ?? null;
$contractId = $mapped['contract_id'] ?? $context['contract']?->entity?->id ?? null;
$contractId = $mapped['contract_id'] ?? $context['contract']['entity']->id ?? null;
if (! $reference || ! $contractId) {
return null;
@@ -37,7 +66,15 @@ public function process(Import $import, array $mapped, array $raw, array $contex
];
}
$contractId = $context['contract']->entity->id;
// Fallback: if account.reference is empty, use contract.reference (matching v1 behavior)
if (empty($mapped['reference'])) {
$contractReference = $context['contract']['entity']->reference ?? null;
if ($contractReference) {
$mapped['reference'] = preg_replace('/\s+/', '', trim((string) $contractReference));
}
}
$contractId = $context['contract']['entity']->id;
$mapped['contract_id'] = $contractId;
$existing = $this->resolve($mapped, $context);
@@ -75,6 +112,12 @@ public function process(Import $import, array $mapped, array $raw, array $contex
// Create new account
$account = new Account;
$payload = $this->buildPayload($mapped, $account);
// Ensure required defaults for new accounts
if (!isset($payload['type_id'])) {
$payload['type_id'] = $this->getDefaultAccountTypeId();
}
$account->fill($payload);
$account->save();
@@ -100,7 +143,14 @@ protected function buildPayload(array $mapped, $model): array
foreach ($fieldMap as $source => $target) {
if (array_key_exists($source, $mapped)) {
$payload[$target] = $mapped[$source];
$value = $mapped[$source];
// Normalize decimal fields (convert comma to period)
if (in_array($source, ['balance_amount', 'initial_amount']) && is_string($value)) {
$value = DecimalNormalizer::normalize($value);
}
$payload[$target] = $value;
}
}
@@ -155,4 +205,12 @@ protected function createBalanceChangeActivity(Account $account, float $oldBalan
]);
}
}
/**
* Get default account type ID.
*/
protected function getDefaultAccountTypeId(): int
{
return (int) (\App\Models\AccountType::min('id') ?? 1);
}
}