fixed import
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,22 @@ protected function buildPayload(array $mapped, $model): array
|
||||
}
|
||||
}
|
||||
|
||||
// Handle meta field - merge grouped meta into flat structure
|
||||
if (!empty($mapped['meta']) && is_array($mapped['meta'])) {
|
||||
$metaData = [];
|
||||
foreach ($mapped['meta'] as $grp => $entries) {
|
||||
if (!is_array($entries)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($entries as $k => $v) {
|
||||
$metaData[$k] = $v;
|
||||
}
|
||||
}
|
||||
if (!empty($metaData)) {
|
||||
$payload['meta'] = $metaData;
|
||||
}
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ public function getEntityClass(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Override validate to skip validation if email is empty.
|
||||
* Override validate to skip validation if email is empty or invalid.
|
||||
* Invalid emails should be skipped, not cause transaction rollback.
|
||||
*/
|
||||
public function validate(array $mapped): array
|
||||
{
|
||||
@@ -23,6 +24,12 @@ public function validate(array $mapped): array
|
||||
return ['valid' => true, 'errors' => []];
|
||||
}
|
||||
|
||||
// Validate email format - if invalid, mark as valid to skip instead of failing
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
// Return valid=true but we'll skip it in process()
|
||||
return ['valid' => true, 'errors' => []];
|
||||
}
|
||||
|
||||
return parent::validate($mapped);
|
||||
}
|
||||
|
||||
@@ -48,6 +55,14 @@ public function process(Import $import, array $mapped, array $raw, array $contex
|
||||
];
|
||||
}
|
||||
|
||||
// Skip if email format is invalid
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return [
|
||||
'action' => 'skipped',
|
||||
'message' => 'Invalid email format',
|
||||
];
|
||||
}
|
||||
|
||||
// Resolve person_id from context
|
||||
$personId = $mapped['person_id'] ?? $context['person']['entity']?->id ?? null;
|
||||
|
||||
|
||||
@@ -128,7 +128,20 @@ public function process(Import $import, array $mapped, array $raw, array $contex
|
||||
$payload['type_id'] = $this->getDefaultPersonTypeId();
|
||||
}
|
||||
|
||||
Log::debug('PersonHandler: Payload before fill', [
|
||||
'payload' => $payload,
|
||||
'has_group_id' => isset($payload['group_id']),
|
||||
'group_id_value' => $payload['group_id'] ?? null,
|
||||
]);
|
||||
|
||||
$person->fill($payload);
|
||||
|
||||
Log::debug('PersonHandler: Person attributes after fill', [
|
||||
'attributes' => $person->getAttributes(),
|
||||
'has_group_id' => isset($person->group_id),
|
||||
'group_id_value' => $person->group_id ?? null,
|
||||
]);
|
||||
|
||||
$person->save();
|
||||
|
||||
Log::info('PersonHandler: Created new Person', [
|
||||
|
||||
Reference in New Issue
Block a user