Vtiger_Inventory_Model::getAccountDiscount()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 11
ccs 0
cts 11
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
/**
4
 * Basic Inventory Model Class.
5
 *
6
 * @package Model
7
 *
8
 * @copyright YetiForce S.A.
9
 * @license   YetiForce Public License 6.5 (licenses/LicenseEN.txt or yetiforce.com)
10
 * @author    Mariusz Krzaczkowski <[email protected]>
11
 * @author    Radosław Skrzypczak <[email protected]>
12
 */
13
class Vtiger_Inventory_Model
14
{
15
	/**
16
	 * Field configuration table postfix.
17
	 */
18
	private const TABLE_POSTFIX_BASE = '_invfield';
19
	/**
20
	 * Data table postfix.
21
	 */
22
	private const TABLE_POSTFIX_DATA = '_inventory';
23
	/**
24
	 * Field mapping table postfix.
25
	 */
26
	private const TABLE_POSTFIX_MAP = '_invmap';
27
28
	/**
29
	 * @var string
30
	 */
31
	protected $moduleName;
32
	/**
33
	 * @var \Vtiger_Basic_InventoryField[] Inventory fields
34
	 */
35
	protected $fields;
36
	/**
37
	 * @var string
38
	 */
39
	protected $tableName;
40
41
	/**
42
	 * Gets inventory instance.
43
	 *
44
	 * @param string $moduleName
45
	 *
46
	 * @throws \App\Exceptions\AppException
47
	 *
48 5
	 * @return self
49
	 */
50 5
	public static function getInstance(string $moduleName): self
51 2
	{
52
		if (\App\Cache::staticHas(__METHOD__, $moduleName)) {
53 5
			$instance = \App\Cache::staticGet(__METHOD__, $moduleName);
54 5
		} else {
55 5
			$modelClassName = Vtiger_Loader::getComponentClassName('Model', 'Inventory', $moduleName);
56 5
			$instance = new $modelClassName();
57
			$instance->setModuleName($moduleName);
58 5
			\App\Cache::staticSave(__METHOD__, $moduleName, $instance);
59
		}
60
		return $instance;
61
	}
62
63
	/**
64
	 * Function returns module name.
65
	 *
66 3
	 * @return string
67
	 */
68 3
	public function getModuleName(): string
69
	{
70
		return $this->moduleName;
71
	}
72
73
	/**
74
	 * Sets module name.
75
	 *
76 5
	 * @param string $name
77
	 */
78 5
	protected function setModuleName(string $name)
79 5
	{
80
		$this->moduleName = $name;
81
	}
82
83
	/**
84
	 * Gets table name.
85
	 *
86
	 * @param string $type
87
	 *
88 5
	 * @return string
89
	 */
90 5
	public function getTableName(string $type = self::TABLE_POSTFIX_BASE): string
91 5
	{
92
		if (!isset($this->tableName)) {
93 5
			$this->tableName = CRMEntity::getInstance($this->moduleName)->table_name;
94
		}
95
		return $this->tableName . $type;
96
	}
97
98
	/**
99
	 * Gets data table name.
100
	 *
101 2
	 * @return string
102
	 */
103 2
	public function getDataTableName(): string
104
	{
105
		return $this->getTableName(self::TABLE_POSTFIX_DATA);
106
	}
107
108
	/**
109
	 * Gets inventory fields.
110
	 *
111
	 * @throws \App\Exceptions\AppException
112
	 *
113 2
	 * @return \Vtiger_Basic_InventoryField[]
114
	 */
115 2
	public function getFields(): array
116 2
	{
117 2
		if (!isset($this->fields)) {
118 2
			$this->fields = [];
119 2
			$dataReader = (new \App\Db\Query())->from($this->getTableName())->indexBy('columnname')
120 2
				->orderBy(['block' => SORT_ASC, 'sequence' => SORT_ASC])->createCommand()->query();
121 2
			while ($row = $dataReader->read()) {
122 2
				$fieldModel = Vtiger_Basic_InventoryField::getInstance($this->moduleName, $row['invtype']);
123
				$this->setFieldData($fieldModel, $row);
124
				$this->fields[$row['columnname']] = $fieldModel;
125 2
			}
126
		}
127
		return $this->fields;
128
	}
129
130
	/**
131
	 * Gets inventory field model.
132
	 *
133
	 * @param string $fieldName
134
	 *
135
	 * @throws \App\Exceptions\AppException
136
	 *
137 2
	 * @return \Vtiger_Basic_InventoryField|null
138
	 */
139 2
	public function getField(string $fieldName): ?Vtiger_Basic_InventoryField
140
	{
141
		return $this->getFields()[$fieldName] ?? null;
142
	}
143
144
	/**
145
	 * Gets inventory field model by ID.
146
	 *
147
	 * @param int $fieldId
148
	 *
149
	 * @return \Vtiger_Basic_InventoryField|null
150
	 */
151
	public function getFieldById(int $fieldId): ?Vtiger_Basic_InventoryField
152
	{
153
		$fieldModel = null;
154
		if (\App\Cache::staticHas(__METHOD__, $fieldId)) {
155
			$fieldModel = \App\Cache::staticGet(__METHOD__, $fieldId);
156
		} else {
157
			$row = (new \App\Db\Query())->from($this->getTableName())->where(['id' => $fieldId])->one();
158
			if ($row) {
159
				$fieldModel = $this->getFieldCleanInstance($row['invtype']);
160
				$this->setFieldData($fieldModel, $row);
161
			}
162
			\App\Cache::staticSave(__METHOD__, $fieldId, $fieldModel);
163
		}
164
		return $fieldModel;
165
	}
166
167
	/**
168
	 * Function that returns all the fields by blocks.
169
	 *
170
	 * @throws \App\Exceptions\AppException
171
	 *
172
	 * @return array
173
	 */
174
	public function getFieldsByBlocks(): array
175
	{
176
		$fieldList = [];
177
		foreach ($this->getFields() as $fieldName => $fieldModel) {
178
			$fieldList[$fieldModel->get('block')][$fieldName] = $fieldModel;
179
		}
180
		return $fieldList;
181
	}
182
183
	/**
184
	 * Gets inventory fields by type.
185
	 *
186
	 * @param string $type
187
	 *
188
	 * @throws \App\Exceptions\AppException
189
	 *
190
	 * @return \Vtiger_Basic_InventoryField[]
191
	 */
192
	public function getFieldsByType(string $type): array
193
	{
194
		$fieldList = [];
195
		foreach ($this->getFields() as $fieldName => $fieldModel) {
196
			if ($type === $fieldModel->getType()) {
197
				$fieldList[$fieldName] = $fieldModel;
198
			}
199
		}
200
		return $fieldList;
201
	}
202
203
	/**
204
	 * Gets the field for the view.
205
	 *
206
	 * @param string $view
207
	 *
208
	 * @throws \App\Exceptions\AppException
209
	 *
210
	 * @return \Vtiger_Basic_InventoryField[]
211
	 */
212
	public function getFieldsForView(string $view): array
213
	{
214
		$fieldList = [];
215
		switch ($view) {
216
			case 'DetailPreview':
217
			case 'Detail':
218
				foreach ($this->getFields() as $fieldName => $fieldModel) {
219
					if ($fieldModel->isVisibleInDetail()) {
220
						$fieldList[$fieldModel->get('block')][$fieldName] = $fieldModel;
221
					}
222
				}
223
				break;
224
			default:
225
				break;
226
		}
227
		return $fieldList;
228
	}
229
230
	/**
231
	 * Getting summary fields name.
232
	 *
233
	 * @throws \App\Exceptions\AppException
234
	 *
235 2
	 * @return string[]
236
	 */
237 2
	public function getSummaryFields(): array
238 2
	{
239 2
		$summaryFields = [];
240 2
		foreach ($this->getFields() as $name => $field) {
241
			if ($field->isSummary()) {
242
				$summaryFields[$name] = $name;
243 2
			}
244
		}
245
		return $summaryFields;
246
	}
247
248
	/**
249
	 * Sets inventory field data.
250
	 *
251
	 * @param \Vtiger_Basic_InventoryField $fieldModel
252 2
	 * @param array                        $row
253
	 */
254 2
	public function setFieldData(Vtiger_Basic_InventoryField $fieldModel, array $row)
255 2
	{
256 2
		$fieldModel->set('id', (int) $row['id'])
257 2
			->set('columnName', $row['columnname'])
258 2
			->set('label', $row['label'])
259 2
			->set('presence', (int) $row['presence'])
260 2
			->set('defaultValue', $row['defaultvalue'])
261 2
			->set('sequence', (int) $row['sequence'])
262 2
			->set('block', (int) $row['block'])
263 2
			->set('displayType', (int) $row['displaytype'])
264 2
			->set('params', $row['params'])
265
			->set('colSpan', (int) $row['colspan']);
266
	}
267
268
	/**
269
	 * Checks if inventory field exists.
270
	 *
271
	 * @param string $fieldName
272
	 *
273
	 * @throws \App\Exceptions\AppException
274
	 *
275 1
	 * @return bool
276
	 */
277 1
	public function isField(string $fieldName): bool
278
	{
279
		return isset($this->getFields()[$fieldName]);
280
	}
281
282
	/**
283
	 * Gets clean inventory field instance.
284
	 *
285
	 * @param string $type
286
	 *
287
	 * @throws \App\Exceptions\AppException
288
	 *
289
	 * @return \Vtiger_Basic_InventoryField
290
	 */
291
	public function getFieldCleanInstance(string $type): Vtiger_Basic_InventoryField
292
	{
293
		return \Vtiger_Basic_InventoryField::getInstance($this->getModuleName(), $type);
294
	}
295
296
	/**
297
	 * Function to get data of inventory for record.
298
	 *
299
	 * @param int                       $recordId
300
	 * @param string                    $moduleName
301
	 * @param \Vtiger_Paging_Model|null $pagingModel
302
	 *
303
	 * @throws \App\Exceptions\AppException
304 1
	 *
305
	 * @return array
306 1
	 */
307 1
	public static function getInventoryDataById(int $recordId, string $moduleName, ?Vtiger_Paging_Model $pagingModel = null): array
308 1
	{
309
		$inventory = self::getInstance($moduleName);
310
		$query = (new \App\Db\Query())->from($inventory->getTableName(self::TABLE_POSTFIX_DATA))->indexBy('id')->where(['crmid' => $recordId]);
311 1
		if ($inventory->isField('seq')) {
312
			$query->orderBy(['seq' => SORT_ASC]);
313
		}
314
		if ($pagingModel) {
315
			$pageLimit = $pagingModel->getPageLimit();
316
			if (0 !== $pagingModel->get('limit')) {
317
				$query->limit($pageLimit + 1)->offset($pagingModel->getStartIndex());
318
			}
319
			$rows = $query->all();
320
			$count = \count($rows);
321
			if ($count > $pageLimit) {
322
				array_pop($rows);
323
				$pagingModel->set('nextPageExists', true);
324
			} else {
325
				$pagingModel->set('nextPageExists', false);
326
			}
327
			$pagingModel->calculatePageRange($count);
328
			return $rows;
329
		}
330
		return $query->all();
331
	}
332
333
	/**
334
	 * Save inventory field.
335
	 *
336
	 * @param \Vtiger_Basic_InventoryField $fieldModel
337
	 *
338
	 * @throws \yii\db\Exception
339
	 *
340
	 * @return bool
341
	 */
342
	public function saveField(Vtiger_Basic_InventoryField $fieldModel): bool
343
	{
344
		$db = \App\Db::getInstance();
345
		$tableName = $this->getTableName();
346
		if (!$fieldModel->has('sequence')) {
347
			$fieldModel->set('sequence', $db->getUniqueID($tableName, 'sequence', false));
348
		}
349
		if ($fieldModel->isEmpty('id') && !$fieldModel->isOnlyOne()) {
350
			$id = (new \App\Db\Query())->from($tableName)->where(['invtype' => $fieldModel->getType()])->max('id') + 1;
351
			$fieldModel->set('columnName', $fieldModel->getColumnName() . $id);
352
		}
353
		$transaction = $db->beginTransaction();
354
		try {
355
			$data = array_change_key_case($fieldModel->getData(), CASE_LOWER);
356
			if ($fieldModel->isEmpty('id')) {
357
				$table = $this->getTableName(self::TABLE_POSTFIX_DATA);
358
				vtlib\Utils::addColumn($table, $fieldModel->getColumnName(), $fieldModel->getDBType());
359
				foreach ($fieldModel->getCustomColumn() as $column => $criteria) {
360
					vtlib\Utils::addColumn($table, $column, $criteria);
361
				}
362
				$result = $db->createCommand()->insert($tableName, $data)->execute();
363
				$fieldModel->set('id', $db->getLastInsertID("{$tableName}_id_seq"));
364
			} else {
365
				$result = $db->createCommand()->update($tableName, $data, ['id' => $fieldModel->get('id')])->execute();
366
			}
367
			$transaction->commit();
368
		} catch (\Throwable $ex) {
369
			$transaction->rollBack();
370
			\App\Log::error($ex->__toString());
371
			$result = false;
372
		}
373
374
		return (bool) $result;
375
	}
376
377
	/**
378
	 * Delete inventory field.
379
	 *
380
	 * @param string $fieldName
381
	 *
382
	 * @throws \yii\db\Exception
383
	 *
384
	 * @return bool
385
	 */
386
	public function deleteField(string $fieldName): bool
387
	{
388
		$db = \App\Db::getInstance();
389
		$dbCommand = $db->createCommand();
390
		$transaction = $db->beginTransaction();
391
		$result = false;
392
		try {
393
			$fieldModel = $this->getField($fieldName);
394
			$columnsArray = array_keys($fieldModel->getCustomColumn());
395
			$columnsArray[] = $fieldName;
396
			if (isset($fieldModel->shared)) {
397
				foreach ($fieldModel->shared as $column => $columnShared) {
398
					if ($this->isField($columnShared) && false !== ($key = array_search($column, $columnsArray))) {
399
						unset($columnsArray[$key]);
400
					}
401
				}
402
			}
403
			$dbCommand->delete($this->getTableName(), ['columnname' => $fieldName])->execute();
404
			if ('seq' !== $fieldName) {
405
				foreach ($columnsArray as $column) {
406
					$dbCommand->dropColumn($this->getTableName(self::TABLE_POSTFIX_DATA), $column)->execute();
407
				}
408
			}
409
			$transaction->commit();
410
			$result = true;
411
		} catch (\Throwable $ex) {
412
			$transaction->rollBack();
413
			\App\Log::error($ex->__toString());
414
		}
415
		return $result;
416
	}
417
418
	/**
419
	 * Save sequence field.
420
	 *
421
	 * @param int[] $sequenceList
422
	 *
423
	 * @throws \yii\db\Exception
424
	 *
425
	 * @return int
426
	 */
427
	public function saveSequence(array $sequenceList): int
428
	{
429
		$db = \App\Db::getInstance();
430
		$case = 'CASE id';
431
		foreach ($sequenceList as $sequence => $id) {
432
			$case .= " WHEN {$db->quoteValue($id)} THEN {$db->quoteValue($sequence)}";
433
		}
434
		$case .= ' END ';
435
		return $db->createCommand()->update($this->getTableName(), ['sequence' => new \yii\db\Expression($case)], ['id' => $sequenceList])->execute();
436
	}
437
438
	/**
439
	 * Retrieve list of all fields.
440
	 *
441
	 * @throws \App\Exceptions\AppException
442
	 *
443
	 * @return \Vtiger_Basic_InventoryField[] Fields instance
444
	 */
445
	public function getFieldsTypes(): array
446
	{
447
		$moduleName = $this->getModuleName();
448
		if (\App\Cache::has(__METHOD__, $moduleName)) {
449
			$inventoryTypes = \App\Cache::get(__METHOD__, $moduleName);
450
		} else {
451
			$fieldPaths = ["modules/$moduleName/inventoryfields/"];
452
			if ('Vtiger' !== $moduleName) {
453
				$fieldPaths[] = 'modules/Vtiger/inventoryfields/';
454
			}
455
			$inventoryTypes = [];
456
			foreach ($fieldPaths as $fieldPath) {
457
				if (!is_dir($fieldPath)) {
458
					continue;
459
				}
460
				foreach (new DirectoryIterator($fieldPath) as $object) {
461
					if ('php' === $object->getExtension() && 'Basic' !== ($type = $object->getBasename('.php')) && !isset($inventoryTypes[$type])) {
462
						$inventoryTypes[$type] = Vtiger_Basic_InventoryField::getInstance($moduleName, $type);
463
					}
464
				}
465
			}
466
			\App\Cache::save(__METHOD__, $moduleName, $inventoryTypes);
467
		}
468
		return $inventoryTypes;
469
	}
470
471
	/**
472
	 * Gets all columns.
473
	 *
474
	 * @throws \App\Exceptions\AppException
475
	 *
476 1
	 * @return astring[]
477
	 */
478 1
	public function getAllColumns()
479 1
	{
480 1
		$columns = [];
481
		foreach ($this->getFields() as $field) {
482 1
			$columns[] = $field->getColumnName();
483 1
			foreach ($field->getCustomColumn() as $name => $field) {
0 ignored issues
show
Comprehensibility Bug introduced by
$field is overwriting a variable from outer foreach loop.
Loading history...
484 1
				$columns[] = $name;
485 1
			}
486
		}
487 1
		return $columns;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $columns returns an array which contains values of type string which are incompatible with the documented value type astring.
Loading history...
488
	}
489 1
490
	/**
491
	 * Function return autocomplete fields.
492
	 *
493
	 * @return array
494
	 */
495
	public function getAutoCompleteFields()
496
	{
497
		$moduleName = $this->getModuleName();
498
		if (\App\Cache::has(__METHOD__, $moduleName)) {
499
			$fields = \App\Cache::get(__METHOD__, $moduleName);
500
		} else {
501
			$fields = [];
502
			$dataReader = (new \App\Db\Query())->from($this->getTableName(self::TABLE_POSTFIX_MAP))->createCommand()->query();
503
			while ($row = $dataReader->read()) {
504
				$fields[$row['module']][$row['tofield']] = $row;
505
			}
506
			App\Cache::save(__METHOD__, $moduleName, $fields);
507
		}
508
		return $fields;
509
	}
510
511
	/**
512
	 * Function to get custom values to complete in inventory.
513
	 *
514
	 * @param string              $sourceFieldName
515
	 * @param Vtiger_Record_Model $recordModel
516
	 *
517
	 * @return array
518
	 */
519
	public function getCustomAutoComplete(string $sourceFieldName, Vtiger_Record_Model $recordModel)
520
	{
521
		$values = [];
522
		$inventoryMap = App\Config::module($this->getModuleName(), 'INVENTORY_ON_SELECT_AUTO_COMPLETE');
523
		if ($inventoryMap) {
524
			foreach ($inventoryMap as $fieldToComplete => $mapping) {
525
				if (isset($mapping[$sourceFieldName]) && method_exists($this, $mapping[$sourceFieldName])) {
526
					$methodName = $mapping[$sourceFieldName];
527
					$values[$fieldToComplete] = $this->{$methodName}($recordModel);
528
				}
529
			}
530
		}
531
		return $values;
532
	}
533
534
	/**
535
	 * Gets data from record.
536
	 *
537
	 * @param \Vtiger_Record_Model $recordModel
538
	 *
539
	 * @return float
540
	 */
541
	public function getInventoryPrice(Vtiger_Record_Model $recordModel)
542
	{
543
		return $recordModel->isEmpty('sum_total') ? 0 : $recordModel->get('sum_total');
544
	}
545
546
	/**
547
	 * Function to get list elements in iventory as html code.
548
	 *
549
	 * @param \Vtiger_Record_Model $recodModel
550
	 *
551
	 * @throws \App\Exceptions\AppException
552
	 *
553
	 * @return string
554
	 */
555 1
	public function getInventoryListName(Vtiger_Record_Model $recodModel)
556
	{
557 1
		$field = $this->getField('name');
558 1
		$html = '<ul>';
559 1
		foreach ($recodModel->getInventoryData() as $data) {
560
			$html .= '<li>';
561 1
			$html .= $field->getDisplayValue($data['name']);
562
			$html .= '</li>';
563
		}
564
		return $html . '</ul>';
565
	}
566
567
	/**
568
	 * Gets template to purify.
569 2
	 *
570
	 * @throws \App\Exceptions\AppException
571 2
	 *
572 2
	 * @return array
573
	 */
574 2
	public function getPurifyTemplate(): array
575 2
	{
576 2
		$template = [];
577 2
		foreach ($this->getFields() as $fieldModel) {
578 2
			$template += $fieldModel->getPurifyType();
579 2
		}
580
		return $template;
581 2
	}
582
583 2
	/**
584 2
	 * Get discounts configuration.
585
	 *
586
	 * @param string $key
587
	 *
588
	 * @return mixed config data
589
	 */
590
	public static function getDiscountsConfig(string $key = '')
591
	{
592
		if (\App\Cache::has('Inventory', 'DiscountConfiguration')) {
593
			$config = \App\Cache::get('Inventory', 'DiscountConfiguration');
594
		} else {
595
			$config = [];
596
			$dataReader = (new \App\Db\Query())->from('a_#__discounts_config')->createCommand(\App\Db::getInstance('admin'))->query();
597
			while ($row = $dataReader->read()) {
598
				$value = $row['value'];
599
				if (\in_array($row['param'], ['discounts'])) {
600
					$value = explode(',', $value);
601
				}
602
				$config[$row['param']] = $value;
603
			}
604
			\App\Cache::save('Inventory', 'DiscountConfiguration', $config, \App\Cache::LONG);
605
		}
606
		return $key ? $config[$key] : $config;
607
	}
608 2
609
	/**
610 2
	 * Get global discounts list.
611 2
	 *
612
	 * @return array discounts list
613 2
	 */
614 2
	public function getGlobalDiscounts()
615 2
	{
616 2
		if (\App\Cache::has('Inventory', 'Discounts')) {
617 2
			return \App\Cache::get('Inventory', 'Discounts');
618 2
		}
619
		$discounts = (new App\Db\Query())->from('a_#__discounts_global')->where(['status' => 0])
620 2
			->createCommand(App\Db::getInstance('admin'))->queryAllByGroup(1);
621
		\App\Cache::save('Inventory', 'Discounts', $discounts, \App\Cache::LONG);
622 2
		return $discounts;
623 2
	}
624
625
	/**
626
	 * Get tax configuration.
627
	 *
628
	 * @return array config data
629
	 */
630
	public static function getTaxesConfig()
631 1
	{
632
		if (\App\Cache::has('Inventory', 'TaxConfiguration')) {
633 1
			return \App\Cache::get('Inventory', 'TaxConfiguration');
634 1
		}
635
		$config = [];
636 1
		$dataReader = (new App\Db\Query())->from('a_#__taxes_config')->createCommand(App\Db::getInstance('admin'))->query();
637 1
		while ($row = $dataReader->read()) {
638 1
			$value = $row['value'];
639 1
			if (\in_array($row['param'], ['taxs'])) {
640
				$value = explode(',', $value);
641
			}
642
			$config[$row['param']] = $value;
643
		}
644
		\App\Cache::save('Inventory', 'TaxConfiguration', $config, \App\Cache::LONG);
645
		return $config;
646
	}
647
648
	/**
649
	 * Get global tax list.
650
	 *
651
	 * @return array tax list
652
	 */
653
	public static function getGlobalTaxes()
654
	{
655
		if (\App\Cache::has('Inventory', 'Taxes')) {
656
			return \App\Cache::get('Inventory', 'Taxes');
657
		}
658
		$taxes = (new App\Db\Query())->from('a_#__taxes_global')->where(['status' => 0])
659
			->createCommand(App\Db::getInstance('admin'))->queryAllByGroup(1);
660
		\App\Cache::save('Inventory', 'Taxes', $taxes, \App\Cache::LONG);
661
		return $taxes;
662
	}
663
664
	/**
665
	 * Get default global tax .
666
	 *
667
	 * @return array tax list
668
	 */
669
	public static function getDefaultGlobalTax()
670
	{
671
		if (\App\Cache::has('Inventory', 'DefaultTax')) {
672
			return \App\Cache::get('Inventory', 'DefaultTax');
673
		}
674
		$defaultTax = (new App\Db\Query())->from('a_#__taxes_global')->where(['status' => 0])->andWhere(['default' => 1])
675
			->one();
676
		\App\Cache::save('Inventory', 'DefaultTax', $defaultTax, \App\Cache::LONG);
677
		return $defaultTax;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $defaultTax could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
678
	}
679
680
	/**
681
	 * Get discount from the account.
682
	 *
683
	 * @param string $moduleName    Module name
684
	 * @param int    $record        Record ID
685
	 * @param mixed  $relatedRecord
686
	 *
687
	 * @return array
688
	 */
689
	public function getAccountDiscount($relatedRecord)
690
	{
691
		$discount = 0;
692
		$discountField = 'discount';
693
		$recordName = '';
694
		if (!empty($relatedRecord)) {
695
			$accountRecordModel = Vtiger_Record_Model::getInstanceById($relatedRecord);
696
			$discount = $accountRecordModel->get($discountField);
697
			$recordName = $accountRecordModel->getName();
698
		}
699
		return ['discount' => $discount, 'name' => $recordName];
700
	}
701
702
	/**
703
	 * Get tax from the account.
704
	 *
705
	 * @param int $relatedRecord Record ID
706
	 *
707
	 * @return array
708
	 */
709 2
	public function getAccountTax($relatedRecord)
710
	{
711 2
		$sourceModule = 'Accounts';
712 2
		$recordName = '';
713 2
		$accountTaxes = [];
714 2
		if (!empty($relatedRecord) && \App\Record::isExists($relatedRecord, $sourceModule) && ($taxField = current(Vtiger_Module_Model::getInstance($sourceModule)->getFieldsByUiType(303))) && $taxField->isActiveField()) {
715 2
			$accountRecordModel = Vtiger_Record_Model::getInstanceById($relatedRecord, $sourceModule);
716
			$accountTaxes = Vtiger_Taxes_UIType::getValues($accountRecordModel->get($taxField->getName()));
717 2
			$recordName = $accountRecordModel->getName();
718
		}
719 2
		return ['taxes' => $accountTaxes, 'name' => $recordName];
720 2
	}
721 2
722
	/**
723
	 * Create inventory tables.
724 2
	 */
725
	public function createInventoryTables()
726 2
	{
727 2
		$db = \App\Db::getInstance();
728
		$importer = new \App\Db\Importers\Base();
729 2
		$focus = CRMEntity::getInstance($this->getModuleName());
730
		$dataTableName = $this->getTableName(self::TABLE_POSTFIX_DATA);
731
		$mapTableName = $this->getTableName(self::TABLE_POSTFIX_MAP);
732 2
		$tables = [
733
			$dataTableName => [
734 2
				'columns' => [
735 2
					'id' => $importer->primaryKey(10),
736 2
					'crmid' => $importer->integer(10),
737 2
					'seq' => $importer->integer(10),
738 2
				],
739 2
				'index' => [
740 2
					["{$dataTableName}_crmid_idx", 'crmid'],
741 2
				],
742 2
				'engine' => 'InnoDB',
743 2
				'charset' => 'utf8',
744 2
				'foreignKey' => [
745
					["{$dataTableName}_crmid_fk", $dataTableName, 'crmid', $focus->table_name, $focus->table_index, 'CASCADE', null]
746 2
				]
747 2
			],
748
			$this->getTableName(self::TABLE_POSTFIX_BASE) => [
749
				'columns' => [
750
					'id' => $importer->primaryKey(),
751 2
					'columnname' => $importer->stringType(30)->notNull(),
752 2
					'label' => $importer->stringType(50)->notNull(),
753 2
					'invtype' => $importer->stringType(30)->notNull(),
754
					'presence' => $importer->smallInteger(1)->unsigned()->notNull()->defaultValue(0),
755
					'defaultvalue' => $importer->stringType(),
756 2
					'sequence' => $importer->integer(10)->unsigned()->notNull(),
757
					'block' => $importer->smallInteger(1)->unsigned()->notNull(),
758 2
					'displaytype' => $importer->smallInteger(1)->unsigned()->notNull()->defaultValue(1),
759 2
					'params' => $importer->text(),
760
					'colspan' => $importer->smallInteger(1)->unsigned()->notNull()->defaultValue(1),
761 2
				],
762 2
				'engine' => 'InnoDB',
763 2
				'charset' => 'utf8',
764 2
			],
765 2
			$mapTableName => [
766 2
				'columns' => [
767 2
					'module' => $importer->stringType(50)->notNull(),
768 2
					'field' => $importer->stringType(50)->notNull(),
769 2
					'tofield' => $importer->stringType(50)->notNull(),
770
				],
771
				'primaryKeys' => [
772
					["{$mapTableName}_pk", ['module', 'field', 'tofield']],
773 2
				],
774
				'engine' => 'InnoDB',
775
				'charset' => 'utf8',
776
			]];
777
		$base = new \App\Db\Importer();
778
		$base->dieOnError = App\Config::debug('SQL_DIE_ON_ERROR');
779
		foreach ($tables as $tableName => $data) {
780
			if (!$db->isTableExists($tableName)) {
781
				$importer->tables = [$tableName => $data];
782
				$base->addTables($importer);
783
				if (isset($data['foreignKey'])) {
784
					$importer->foreignKey = $data['foreignKey'];
785
					$base->addForeignKey($importer);
786
				}
787
			}
788
		}
789
	}
790
791
	/**
792
	 * Load row data by record Id.
793
	 *
794
	 * @param int   $recordId
795
	 * @param array $params
796
	 *
797
	 * @return array
798
	 */
799
	public function loadRowData(int $recordId, array $params = []): array
800
	{
801
		$recordModel = Vtiger_Record_Model::getInstanceById($recordId);
802
		$recordModuleName = $recordModel->getModuleName();
803
		$data = [
804
			'name' => $recordId,
805
		];
806
		if (!$recordModel->isEmpty('description')) {
807
			$data['comment1'] = $recordModel->get('description');
808
		}
809
		if (\in_array($recordModuleName, ['Products', 'Services'])) {
810
			$currencyId = $params['currency'] ?? \App\Fields\Currency::getDefault()['id'];
811
			if (($fieldModel = $recordModel->getField('unit_price')) && $fieldModel->isActiveField()) {
812
				$data['price'] = $fieldModel->getUITypeModel()->getValueForCurrency($recordModel->get($fieldModel->getName()), $currencyId);
0 ignored issues
show
Bug introduced by
The method getValueForCurrency() does not exist on Vtiger_Base_UIType. It seems like you code against a sub-type of Vtiger_Base_UIType such as Vtiger_MultiCurrency_UIType. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

812
				$data['price'] = $fieldModel->getUITypeModel()->/** @scrutinizer ignore-call */ getValueForCurrency($recordModel->get($fieldModel->getName()), $currencyId);
Loading history...
813
			}
814
			if (($fieldModel = $recordModel->getField('purchase')) && $fieldModel->isActiveField()) {
815
				$data['purchase'] = $fieldModel->getUITypeModel()->getValueForCurrency($recordModel->get($fieldModel->getName()), $currencyId);
816
			}
817
		}
818
		if ($autoCompleteField = ($this->getAutoCompleteFields()[$recordModuleName] ?? [])) {
819
			foreach ($autoCompleteField as $field) {
820
				$fieldModel = $recordModel->getField($field['field']);
821
				if ($fieldModel && ($fieldValue = $recordModel->get($field['field']))) {
822
					$data[$field['tofield']] = $fieldValue;
823
				}
824
			}
825
		}
826
		return $data;
827
	}
828
}
829