Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
65.22% covered (warning)
65.22%
30 / 46
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImportMappingConfig
66.67% covered (warning)
66.67%
30 / 45
33.33% covered (danger)
33.33%
1 / 3
10.37
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
 fromArray
87.50% covered (warning)
87.50%
14 / 16
0.00% covered (danger)
0.00%
0 / 1
4.03
 toArray
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\DataExchange\Domain\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11/**
12 * Value Object encapsulating configuration and column mappings for an import process.
13 *
14 * @package App\Core\DataExchange\Domain\Model
15 */
16final readonly class ImportMappingConfig
17{
18    public const string STRATEGY_INSERT_ALL = 'insert_all';
19    public const string STRATEGY_SKIP_DUPLICATES = 'skip_duplicates';
20    public const string STRATEGY_UPDATE_DUPLICATES = 'update_duplicates';
21
22    public string $moduleName;
23    /** @var array<string, string> */
24    public array $fieldMappings;
25    /** @var array<string, string> */
26    public array $columnMapping;
27    /** @var array<string, mixed> */
28    public array $defaultValues;
29    public string $deduplicationStrategy;
30    public ?string $deduplicationField;
31    public ?string $uniqueIdentifierField;
32    public string $dateFormat;
33    public bool $dryRun;
34    public bool $isDryRun;
35    public bool $isAsync;
36
37    /**
38     * ImportMappingConfig constructor.
39     *
40     * @param string                $moduleName            Target module machine name.
41     * @param array<string, string> $columnMapping         Map of file column name to CRM field_key.
42     * @param array<string, mixed>  $defaultValues         Default fallback values for unmapped fields.
43     * @param string                $deduplicationStrategy Conflict resolution strategy.
44     * @param string|null           $uniqueIdentifierField Unique CRM field key for matching duplicates.
45     * @param string                $dateFormat            Incoming date format strategy.
46     * @param array<string, mixed>|bool $isDryRun              Simulation flag or execution options.
47     */
48    public function __construct(
49        string $moduleName = '',
50        array $columnMapping = [],
51        array $defaultValues = [],
52        string $deduplicationStrategy = self::STRATEGY_INSERT_ALL,
53        ?string $uniqueIdentifierField = null,
54        string $dateFormat = 'auto',
55        array|bool $isDryRun = false
56    ) {
57        $this->moduleName = $moduleName;
58        $this->fieldMappings = $columnMapping;
59        $this->columnMapping = $columnMapping;
60        $this->defaultValues = $defaultValues;
61        $this->deduplicationStrategy = $deduplicationStrategy;
62        $this->deduplicationField = $uniqueIdentifierField;
63        $this->uniqueIdentifierField = $uniqueIdentifierField;
64        $this->dateFormat = $dateFormat;
65
66        if (is_array($isDryRun)) {
67            $dry = !empty($isDryRun['is_dry_run']) || !empty($isDryRun['dry_run']);
68            $async = !empty($isDryRun['is_async']);
69        } else {
70            $dry = $isDryRun;
71            $async = false;
72        }
73
74        $this->dryRun = $dry;
75        $this->isDryRun = $dry;
76        $this->isAsync = $async;
77    }
78
79    /**
80     * Reconstitutes configuration from array.
81     *
82     * @param array<string, mixed> $data Raw input array.
83     * @return self Value object.
84     */
85    public static function fromArray(array $data): self
86    {
87        $mappings = (array) ($data['column_mapping'] ?? ($data['field_mappings'] ?? []));
88        $unique = null;
89        if (!empty($data['unique_identifier_field'])) {
90            $unique = (string) $data['unique_identifier_field'];
91        } elseif (!empty($data['deduplication_field'])) {
92            $unique = (string) $data['deduplication_field'];
93        }
94
95        $isDry = !empty($data['is_dry_run']) || !empty($data['dry_run']);
96
97        return new self(
98            moduleName:            (string) ($data['module_name'] ?? ''),
99            columnMapping:         $mappings,
100            defaultValues:         (array) ($data['default_values'] ?? []),
101            deduplicationStrategy: (string) ($data['deduplication_strategy'] ?? self::STRATEGY_INSERT_ALL),
102            uniqueIdentifierField: $unique,
103            dateFormat:            (string) ($data['date_format'] ?? 'auto'),
104            isDryRun:              ['is_dry_run' => $isDry, 'is_async' => (bool) ($data['is_async'] ?? false)]
105        );
106    }
107
108    /**
109     * Serializes configuration to array.
110     *
111     * @return array<string, mixed> Serialized data.
112     */
113    public function toArray(): array
114    {
115        return [
116            'module_name'             => $this->moduleName,
117            'field_mappings'          => $this->fieldMappings,
118            'column_mapping'          => $this->columnMapping,
119            'default_values'          => $this->defaultValues,
120            'deduplication_strategy'  => $this->deduplicationStrategy,
121            'deduplication_field'     => $this->deduplicationField,
122            'unique_identifier_field' => $this->uniqueIdentifierField,
123            'date_format'             => $this->dateFormat,
124            'dry_run'                 => $this->dryRun,
125            'is_dry_run'              => $this->isDryRun,
126            'is_async'                => $this->isAsync,
127        ];
128    }
129}