Test Setup Failed
Push — developer ( 8f3936...70f22f )
by Mariusz
20:02
created

Map::setErrorLog()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 11
rs 9.6111
cc 5
nc 6
nop 1
1
<?php
2
3
/**
4
 * Comarch abstract base map file.
5
 *
6
 * The file is part of the paid functionality. Using the file is allowed only after purchasing a subscription.
7
 * File modification allowed only with the consent of the system producer.
8
 *
9
 * @package Integration
10
 *
11
 * @copyright YetiForce S.A.
12
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
13
 * @author    Mariusz Krzaczkowski <[email protected]>
14
 */
15
16
namespace App\Integrations\Comarch;
17
18
/**
19
 * Comarch abstract base map class.
20
 */
21
abstract class Map
22
{
23
	/** @var string The name of the field with the identifier in Comarch */
24
	const FIELD_NAME_ID = 'comarch_id';
25
	/** @var string The name of the key with the identifier from Comarch */
26
	const API_NAME_ID = 'id';
27
	/** @var string Skip mode when data is incomplete */
28
	public $skip = false;
29
	/** @var string Map module name. */
30
	protected $moduleName;
31
	/** @var array Mapped fields. */
32
	protected $fieldMap = [];
33
	/** @var array Data from Comarch. */
34
	protected $dataApi = [];
35
	/** @var array Default data from Comarch. */
36
	protected $defaultDataApi = [];
37
	/** @var array Data from YetiForce. */
38
	protected $dataYf = [];
39
	/** @var array Default data from YetiForce. */
40
	protected $defaultDataYf = [];
41
	/** @var \App\Integrations\Comarch\Synchronizer Synchronizer instance */
42
	protected $synchronizer;
43
	/** @var array Dependent synchronizations to be performed during the operation */
44
	protected $dependentSynchronizations = [];
45
	/** @var \Vtiger_Module_Model Module model instance */
46
	protected $moduleModel;
47
	/** @var \Vtiger_Record_Model Record model instance */
48
	protected $recordModel;
49
	/** @var string API map mode: create, update, get. */
50
	protected $modeApi;
51
52
	/** @var string[] Mapped address fields. */
53
	protected $addressMapFields = [
54
		'addresslevel1' => [
55
			'names' => ['get' => 'knt_Kraj', 'create' => 'Kraj', 'update' => 'Kraj'], 'fn' => 'convertCountry'
56
		],
57
		'addresslevel2' => ['names' => ['get' => 'knt_Wojewodztwo', 'create' => 'Wojewodztwo', 'update' => 'Wojewodztwo']],
58
		'addresslevel3' => ['names' => ['get' => 'knt_Powiat', 'create' => 'Powiat', 'update' => 'Powiat']],
59
		'addresslevel4' => ['names' => ['get' => 'knt_Gmina', 'create' => 'Gmina', 'update' => 'Gmina']],
60
		'addresslevel5' => ['names' => ['get' => 'knt_Miasto', 'create' => 'Miasto', 'update' => 'Miasto']],
61
		'addresslevel7' => ['names' => ['get' => 'knt_KodP', 'create' => 'KodP', 'update' => 'KodP']],
62
		'addresslevel8' => ['names' => ['get' => 'knt_Ulica', 'create' => 'Ulica', 'update' => 'Ulica']],
63
		'first_name_' => 'first_name',
64
		'last_name_' => 'last_name',
65
		'phone_' => ['name' => 'phone', 'fn' => 'convertPhone'],
66
		'email_' => 'email',
67
		'company_name_' => 'company',
68
	];
69
70
	/**
71
	 * Constructor.
72
	 *
73
	 * @param \App\Integrations\Comarch\Synchronizer $synchronizer
74
	 */
75
	public function __construct(Synchronizer $synchronizer)
76
	{
77
		$this->synchronizer = $synchronizer;
78
		$this->moduleModel = \Vtiger_Module_Model::getInstance($this->moduleName);
79
	}
80
81
	/**
82
	 * Set data from/for API.
83
	 *
84
	 * @param array $data
85
	 */
86
	public function setDataApi(array $data): void
87
	{
88
		if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
89
			$this->dataApi = $data;
90
			$this->modeApi = 'get';
91
		} else {
92
			$this->dataApi = $this->defaultDataApi;
93
			$this->modeApi = '';
94
		}
95
	}
96
97
	/**
98
	 * Set data from/for YetiForce. YetiForce data is read-only.
99
	 *
100
	 * @param array $data
101
	 * @param bool  $updateRecordModel
102
	 *
103
	 * @return void
104
	 */
105
	public function setDataYf(array $data, bool $updateRecordModel = false): void
106
	{
107
		$this->dataYf = $data;
108
		if ($updateRecordModel) {
109
			$this->recordModel = \Vtiger_Module_Model::getInstance($this->moduleName)->getRecordFromArray($data);
110
		}
111
	}
112
113
	/**
114
	 * Set data from/for YetiForce by record ID. Read/Write YetiForce data.
115
	 *
116
	 * @param int $id
117
	 *
118
	 * @return void
119
	 */
120
	public function setDataYfById(int $id): void
121
	{
122
		$this->recordModel = \Vtiger_Record_Model::getInstanceById($id, $this->moduleName);
123
		$this->dataYf = $this->recordModel->getData();
124
	}
125
126
	/**
127
	 * Checking what is the mode of operation to be performed in the API,
128
	 * along with searching for the same entry in the API.
129
	 *
130
	 * @return void
131
	 */
132
	public function loadModeApi(): void
133
	{
134
		if (empty($this->modeApi)) {
135
			$this->modeApi = empty($this->dataYf[$this::FIELD_NAME_ID]) ? 'create' : 'update';
136
			if (empty($this->dataApi['id']) && ($id = $this->findRecordInApi())) {
137
				$this->dataApi['id'] = $id;
138
				$this->modeApi = 'update';
139
			}
140
		}
141
	}
142
143
	/**
144
	 * Get API mode.
145
	 *
146
	 * @return string|null
147
	 */
148
	public function getModeApi(): ?string
149
	{
150
		return $this->modeApi;
151
	}
152
153
	/**
154
	 * Load record model.
155
	 *
156
	 * @param int|null $id
157
	 */
158
	public function loadRecordModel(?int $id = null): void
159
	{
160
		if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
161
			$this->recordModel = \Vtiger_Record_Model::getInstanceById($id, $this->moduleName);
162
		} else {
163
			$this->recordModel = \Vtiger_Record_Model::getCleanInstance($this->moduleName);
164
		}
165
	}
166
167
	/**
168
	 * Get record model.
169
	 *
170
	 * @return \Vtiger_Record_Model
171
	 */
172
	public function getRecordModel(): \Vtiger_Record_Model
173
	{
174
		return $this->recordModel;
175
	}
176
177
	/**
178
	 * Get module name.
179
	 *
180
	 * @return string
181
	 */
182
	public function getModule(): string
183
	{
184
		return $this->moduleName;
185
	}
186
187
	/**
188
	 * Return fields list.
189
	 *
190
	 * @return array
191
	 */
192
	public function getFields(): array
193
	{
194
		return $this->fieldMap;
195
	}
196
197
	/**
198
	 * Return parsed data in YetiForce format.
199
	 *
200
	 * @param string $type
201
	 * @param bool   $mapped
202
	 *
203
	 * @return array
204
	 */
205
	public function getDataYf(string $type = 'fieldMap', bool $mapped = true): array
206
	{
207
		if ($mapped) {
208
			$this->dataYf = $this->defaultDataYf[$type] ?? [];
209
			foreach ($this->{$type} as $fieldCrm => $field) {
210
				if ($this->skip) {
211
					continue;
212
				}
213
				if (\is_array($field)) {
214
					if (!empty($field['direction']) && 'api' === $field['direction']) {
215
						continue;
216
					}
217
					$key = $field['name'] ?? ($field['names'][$this->modeApi] ?? '');
218
					$field['fieldCrm'] = $fieldCrm;
219
					if (empty($key)) {
220
						$this->synchronizer->controller->log(
221
							"[API>YF][1] No key ($fieldCrm)",
222
							['fieldConfig' => $field, 'data' => $this->dataApi],
223
							null,
224
							true
225
						);
226
					} elseif (\is_array($key)) {
227
						$field['name'] = $key;
228
						$this->loadDataYfMultidimensional($fieldCrm, $field);
229
					} elseif (\array_key_exists($key, $this->dataApi)) {
230
						$this->loadDataYfMap($fieldCrm, $field);
231
					} elseif (!\array_key_exists('optional', $field) || empty($field['optional'])) {
232
						$error = "[API>YF][1] No column {$key} ($fieldCrm)";
233
						\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
234
						$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataApi], null, true);
235
					}
236
				} else {
237
					$this->dataYf[$fieldCrm] = $this->dataApi[$field] ?? null;
238
					if (!\array_key_exists($field, $this->dataApi)) {
239
						$error = "[API>YF][2] No column $field ($fieldCrm)";
240
						\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
241
						$this->synchronizer->controller->log($error, $this->dataApi, null, true);
242
					}
243
				}
244
			}
245
		}
246
		return $this->dataYf;
247
	}
248
249
	/**
250
	 * Return parsed data in YetiForce format.
251
	 *
252
	 * @param bool $mapped
253
	 *
254
	 * @return array
255
	 */
256
	public function getDataApi(bool $mapped = true): array
257
	{
258
		if ($mapped) {
259
			if (!empty($this->dataYf[$this::FIELD_NAME_ID])) {
260
				$this->dataApi['id'] = $this->dataYf[$this::FIELD_NAME_ID];
261
			}
262
			foreach ($this->fieldMap as $fieldCrm => $field) {
263
				if ($this->skip) {
264
					continue;
265
				}
266
				if (\is_array($field)) {
267
					if (!empty($field['direction']) && 'yf' === $field['direction']) {
268
						continue;
269
					}
270
					if (\array_key_exists($fieldCrm, $this->dataYf)) {
271
						$field['fieldCrm'] = $fieldCrm;
272
						if (isset($field['map'])) {
273
							$mapValue = array_search($this->dataYf[$fieldCrm], $field['map']);
274
							if (false !== $mapValue) {
275
								$this->setApiData($mapValue, $field);
276
							} elseif (empty($field['mayNotExist'])) {
277
								$error = "[YF>API] No value `{$this->dataYf[$fieldCrm]}` in map {$fieldCrm}";
278
								\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
279
								$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataYf], null, true);
280
							}
281
						} elseif (isset($field['fn'])) {
282
							$this->setApiData($this->{$field['fn']}($this->dataYf[$fieldCrm], $field, false), $field);
283
						} else {
284
							$this->setApiData($this->dataYf[$fieldCrm], $field);
285
						}
286
					} elseif (!\array_key_exists('optional', $field) || empty($field['optional'])) {
287
						$error = '[YF>API] No field ' . $fieldCrm;
288
						\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
289
						$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataYf], null, true);
290
					}
291
				} else {
292
					$this->dataApi[$field] = $this->dataYf[$fieldCrm] ?? null;
293
					if (!\array_key_exists($fieldCrm, $this->dataYf)) {
294
						$error = '[YF>API] No field ' . $fieldCrm;
295
						\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
296
						$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataYf], null, true);
297
					}
298
				}
299
			}
300
		}
301
		return $this->dataApi;
302
	}
303
304
	/**
305
	 * Set the data to in the appropriate key structure.
306
	 *
307
	 * @param mixed $value
308
	 * @param array $field
309
	 *
310
	 * @return void
311
	 */
312
	public function setApiData($value, array $field): void
313
	{
314
		$key = $field['name'] ?? ($field['names'][$this->modeApi] ?? '');
315
		if (empty($key)) {
316
			$this->synchronizer->controller->log(
317
				"[API>YF][1] No key ({$field['fieldCrm']})",
318
				['fieldConfig' => $field, 'data' => $this->dataApi],
319
				null,
320
				true
321
			);
322
		} elseif (\is_array($key)) {
323
			foreach (array_reverse($key) as $name) {
324
				$value = [$name => $value];
325
			}
326
			$this->dataApi = \App\Utils::merge($this->dataApi, $value);
327
		} else {
328
			$this->dataApi[$key] = $value;
329
		}
330
	}
331
332
	/**
333
	 * Create/update product in YF.
334
	 *
335
	 * @return void
336
	 */
337
	public function saveInYf(): void
338
	{
339
		$moduleModel = $this->recordModel->getModule();
340
		$errorLog = [];
341
		foreach ($this->dataYf as $key => $value) {
342
			if ($fieldModel = $moduleModel->getFieldByName($key)) {
343
				try {
344
					$fieldModel->getUITypeModel()->validate($value);
345
					$this->recordModel->set($key, $value);
346
				} catch (\Throwable $th) {
347
					$errorLog[$key] = [$value, $th->getMessage()]; // TODO weryfikacja
348
				}
349
			}
350
		}
351
		$this->setErrorLog($errorLog);
352
		if ($this->recordModel->isEmpty('assigned_user_id')) {
353
			$this->recordModel->set('assigned_user_id', $this->synchronizer->config->get('assigned_user_id'));
354
		}
355
		if (
356
			$this->recordModel->isEmpty($this::FIELD_NAME_ID)
357
			&& ($id = $this->dataApi['id'] ?? $this->dataApi[$this::API_NAME_ID] ?? 0)
358
			&& $moduleModel->getFieldByName($this::FIELD_NAME_ID)
359
			&& !empty($id)
360
		) {
361
			$this->recordModel->set($this::FIELD_NAME_ID, $id);
362
		}
363
		$this->recordModel->set('comarch_server_id', $this->synchronizer->config->get('id'));
364
		$isNew = empty($this->recordModel->getId());
365
		$this->recordModel->save();
366
		$this->recordModel->ext['isNew'] = $isNew;
367
		if ($isNew && $this->recordModel->get($this::FIELD_NAME_ID)) {
368
			$this->synchronizer->updateMapIdCache(
369
				$this->recordModel->getModuleName(),
370
				$this->recordModel->get($this::FIELD_NAME_ID),
371
				$this->recordModel->getId()
372
			);
373
		}
374
	}
375
376
	/**
377
	 * Create/update product by API.
378
	 *
379
	 * @return void
380
	 */
381
	public function saveInApi(): void
382
	{
383
		throw new \App\Exceptions\AppException('Method not implemented');
384
	}
385
386
	/**
387
	 * Save record in YF from relation action.
388
	 *
389
	 * @param array $field
390
	 *
391
	 * @return int
392
	 */
393
	public function saveFromRelation(array $field): int
394
	{
395
		$id = 0;
396
		if ($dataYf = $this->getDataYf()) {
397
			try {
398
				$id = $this->findRecordInYf();
399
				if (empty($field['onlyCreate']) || empty($id)) {
400
					$this->loadRecordModel($id);
401
					$this->loadAdditionalData();
402
					$this->saveInYf();
403
					$id = $this->getRecordModel()->getId();
404
				}
405
			} catch (\Throwable $ex) {
406
				$error = "[API>YF] Import {$this->moduleName}";
407
				\App\Log::warning($error . "\n" . $ex->getMessage(), $this->synchronizer::LOG_CATEGORY);
408
				$this->synchronizer->controller->log($error, ['YF' => $dataYf, 'API' => $this->dataApi], $ex);
409
			}
410
		}
411
		return $id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $id could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
412
	}
413
414
	/**
415
	 * Find record in YetiFoce.  It can only be based on data from CRM `$this->dataApi`.
416
	 *
417
	 * @return int|null
418
	 */
419
	public function findRecordInYf(): ?int
420
	{
421
		return $this->synchronizer->getYfId($this->dataApi['id'], $this->moduleName);
422
	}
423
424
	/**
425
	 * Find record in API. It can only be based on data from CRM `$this->dataYf`.
426
	 *
427
	 * @return int
428
	 */
429
	public function findRecordInApi(): int
430
	{
431
		return $this->synchronizer->getApiId($this->dataYf['id'], $this->moduleName);
432
	}
433
434
	/**
435
	 * Load additional data.
436
	 *
437
	 * @return void
438
	 */
439
	public function loadAdditionalData(): void
440
	{
441
	}
442
443
	/**
444
	 * Parse data to YetiForce format from multidimensional array.
445
	 *
446
	 * @param string $fieldCrm
447
	 * @param array  $field
448
	 *
449
	 * @return void
450
	 */
451
	protected function loadDataYfMultidimensional(string $fieldCrm, array $field): void
452
	{
453
		$value = $this->dataApi;
454
		$field['fieldCrm'] = $fieldCrm;
455
		foreach ($field['name'] as $name) {
456
			if (\array_key_exists($name, $value)) {
457
				$value = $value[$name];
458
			} else {
459
				$error = "[API>YF][3] No column $name ($fieldCrm)";
460
				if (!\array_key_exists('optional', $field) || empty($field['optional'])) {
461
					\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
462
					$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataApi], null, true);
463
				}
464
			}
465
		}
466
		if (empty($error)) {
467
			$this->loadDataYfMap($fieldCrm, $field, $value);
468
		}
469
	}
470
471
	/**
472
	 * Parse data to YetiForce format from map.
473
	 *
474
	 * @param string     $fieldCrm
475
	 * @param array      $field
476
	 * @param mixed|null $value
477
	 *
478
	 * @return void
479
	 */
480
	protected function loadDataYfMap(string $fieldCrm, array $field, $value = null): void
481
	{
482
		$key = $field['name'] ?? $field['names']['get'];
483
		$value ??= $this->dataApi[$key];
484
		if (isset($field['map'])) {
485
			if (\array_key_exists($value, $field['map'])) {
486
				$this->dataYf[$fieldCrm] = $field['map'][$value];
487
			} elseif (empty($field['mayNotExist'])) {
488
				$value = print_r($value, true);
489
				$error = "[API>YF] No value `{$value}` in map {$key}";
490
				\App\Log::warning($error, $this->synchronizer::LOG_CATEGORY);
491
				$this->synchronizer->controller->log($error, ['fieldConfig' => $field, 'data' => $this->dataApi], null, true);
492
			}
493
		} elseif (isset($field['fn'])) {
494
			$this->dataYf[$fieldCrm] = $this->{$field['fn']}($value, $field, true);
495
		} else {
496
			$this->dataYf[$fieldCrm] = $value;
497
		}
498
	}
499
500
	/**
501
	 * Find by relationship in YF by API ID.
502
	 *
503
	 * @param mixed $value
504
	 * @param array $field
505
	 * @param bool  $fromApi
506
	 *
507
	 * @return int
508
	 */
509
	protected function findByRelationship($value, array $field, bool $fromApi): int
510
	{
511
		$moduleName = $field['moduleName'] ?? $this->moduleName;
512
		if (empty($value)) {
513
			return 0;
514
		}
515
		if ($fromApi) {
516
			return $this->synchronizer->getYfId($value, $moduleName);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->synchroniz...Id($value, $moduleName) could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
517
		}
518
		return $this->synchronizer->getApiId($value, $moduleName);
519
	}
520
521
	/**
522
	 * Add relationship in YF by API ID.findByRelationship.
523
	 *
524
	 * @param mixed $value
525
	 * @param array $field
526
	 * @param bool  $fromApi
527
	 *
528
	 * @return string|array string (YF) or string (API)
529
	 */
530
	protected function addRelationship($value, array $field, bool $fromApi)
531
	{
532
		$moduleName = rtrim($field['moduleName'], 's');
533
		$key = mb_strtolower($moduleName);
534
		if (null === $this->{$key}) {
535
			$this->{$key} = $this->synchronizer->getMapModel($moduleName);
536
		}
537
		$this->{$key}->setDataApi($this->dataApi);
538
		return $this->{$key}->saveFromRelation($field);
539
	}
540
541
	/**
542
	 * Find relationship in YF by API ID.
543
	 *
544
	 * @param mixed $value
545
	 * @param array $field
546
	 * @param bool  $fromApi
547
	 *
548
	 * @return mixed
549
	 */
550
	protected function findBySynchronizer($value, array $field, bool $fromApi)
551
	{
552
		$synchronizer = $this->synchronizer->controller->getSync($field['synchronizer']);
553
		if ($fromApi) {
554
			$return = $synchronizer->getYfValue($value, $field);
555
		} else {
556
			$return = $synchronizer->getApiValue($value, $field);
557
		}
558
		if (null === $return && (!\array_key_exists('optional', $field) || empty($field['optional']))) {
0 ignored issues
show
introduced by
The condition null === $return is always false.
Loading history...
559
			$this->skip = true;
560
			$this->synchronizer->controller->log(
561
				($fromApi ? '[API>YF]' : '[YF>API]') .
562
				"Skip value: {$value} (Field: {$field['fieldCrm']} ,Sync: {$field['synchronizer']})",
563
				['fieldConfig' => $field, 'data' => $this->dataApi],
564
				null,
565
				true
566
			);
567
			$this->setErrorLog([
568
				$field['fieldCrm'] => [$value, 'ERR_REQUIRED_VALUE_MISSING'] // TODO weryfikacja
569
			]);
570
		}
571
		return $return;
572
	}
573
574
	/**
575
	 * Run dependent synchronizer.
576
	 *
577
	 * @param bool $fromApi
578
	 *
579
	 * @return void
580
	 */
581
	protected function runDependentSynchronizer(bool $fromApi): void
582
	{
583
		if (empty($this->dependentSynchronizations)) {
584
			return;
585
		}
586
		foreach ($this->dependentSynchronizations as $synchronizer) {
587
			$synchronizer = $this->synchronizer->controller->getSync($synchronizer);
588
			if ($fromApi) {
589
				if (method_exists($synchronizer, 'importFromDependent')) {
590
					$synchronizer->importFromDependent($this);
591
				}
592
			} else {
593
				if (method_exists($synchronizer, 'exportFromDependent')) {
594
					$synchronizer->exportFromDependent($this);
595
				}
596
			}
597
		}
598
	}
599
600
	/**
601
	 * Convert phone number to system YF format.
602
	 *
603
	 * @param mixed $value
604
	 * @param array $field
605
	 * @param bool  $fromApi
606
	 *
607
	 * @return string
608
	 */
609
	protected function convertPhone($value, array $field, bool $fromApi)
610
	{
611
		if (empty($value) || !$fromApi) {
612
			return $value;
613
		}
614
		$fieldCrm = $field['fieldCrm'];
615
		$parsedData = [$fieldCrm => $value];
616
		$parsedData = \App\Fields\Phone::parsePhone($fieldCrm, $parsedData);
617
		if (empty($parsedData[$fieldCrm])) {
618
			foreach ($parsedData as $key => $value) {
0 ignored issues
show
introduced by
$value is overwriting one of the parameters of this function.
Loading history...
619
				$this->dataYf[$key] = $value;
620
			}
621
			return '';
622
		}
623
		return $parsedData[$fieldCrm];
624
	}
625
626
	/**
627
	 * Convert country to system format.
628
	 *
629
	 * @param mixed $value
630
	 * @param array $field
631
	 * @param bool  $fromApi
632
	 *
633
	 * @return string|null Country name (YF) or Country code (API)
634
	 */
635
	protected function convertCountry($value, array $field, bool $fromApi)
636
	{
637
		if (empty($value)) {
638
			return $value;
639
		}
640
		return $fromApi ? \App\Fields\Country::getCountryName($value) : \App\Fields\Country::getCountryCode($value);
641
	}
642
643
	/**
644
	 * Convert currency.
645
	 *
646
	 * @param mixed $value
647
	 * @param array $field
648
	 * @param bool  $fromApi
649
	 *
650
	 * @return int|string int (YF) or string (API)
651
	 */
652
	protected function convertCurrency($value, array $field, bool $fromApi)
653
	{
654
		if ($fromApi) {
655
			$currency = \App\Fields\Currency::getIdByCode($value);
656
			if (empty($currency)) {
657
				$currency = \App\Fields\Currency::addCurrency($value);
658
			}
659
		} else {
660
			$currency = \App\Fields\Currency::getById($value)['currency_code'];
661
		}
662
		return $currency;
663
	}
664
665
	/**
666
	 * Set error logs.
667
	 *
668
	 * @param array $errorLog
669
	 *
670
	 * @return void
671
	 */
672
	private function setErrorLog(array $errorLog): void
673
	{
674
		$sid = $this->synchronizer->config->get('id');
675
		$log = $this->recordModel->get('log_comarch');
676
		$errors = \App\Json::isEmpty($log) ? [] : \App\Json::decode($log);
677
		if (!empty($errorLog)) {
678
			$errors[$sid] = $errorLog;
679
		} elseif (isset($errors[$sid])) {
680
			unset($errors[$sid]);
681
		}
682
		$this->recordModel->set('log_comarch', empty($errors) ? null : \App\Json::encode($log));
683
	}
684
}
685