Passed
Push — master ( b8b3d1...a7897a )
by
unknown
21:24 queued 18:55
created

InventorySourceItemObserver   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 47
dl 0
loc 192
ccs 0
cts 88
cp 0
rs 10
c 3
b 0
f 0
wmc 15

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getMsiBunchProcessor() 0 3 1
A loadProduct() 0 3 1
B process() 0 49 6
A initializeInventorySourceItem() 0 3 1
A prepareAttributes() 0 16 1
A persistInventorySourceItem() 0 3 1
A setLastEntityId() 0 3 1
A hasInventorySource() 0 3 1
A addSkuSourceItemIdMapping() 0 3 1
1
<?php
2
3
/**
4
 * TechDivision\Import\Product\Msi\Observers\InventorySourceItemObserver
5
 *
6
 * PHP version 7
7
 *
8
 * @author    Tim Wagner <[email protected]>
9
 * @copyright 2018 TechDivision GmbH <[email protected]>
10
 * @license   https://opensource.org/licenses/MIT
11
 * @link      https://github.com/techdivision/import-product-msi
12
 * @link      http://www.techdivision.com
13
 */
14
15
namespace TechDivision\Import\Product\Msi\Observers;
16
17
use TechDivision\Import\Product\Msi\Utils\ColumnKeys;
18
use TechDivision\Import\Product\Msi\Utils\MemberNames;
19
use TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface;
20
use TechDivision\Import\Observers\StateDetectorInterface;
21
use TechDivision\Import\Utils\BackendTypeKeys;
22
use TechDivision\Import\Utils\RegistryKeys;
23
24
/**
25
 * Observer that prepares the MSI source item information found in the CSV file.
26
 *
27
 * @author    Tim Wagner <[email protected]>
28
 * @copyright 2018 TechDivision GmbH <[email protected]>
29
 * @license   https://opensource.org/licenses/MIT
30
 * @link      https://github.com/techdivision/import-product-msi
31
 * @link      http://www.techdivision.com
32
 */
33
class InventorySourceItemObserver extends AbstractMsiImportObserver
34
{
35
36
    /**
37
     * The MSI bunch processor instance.
38
     *
39
     * @var \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface
40
     */
41
    protected $msiBunchProcessor;
42
43
    /**
44
     * Initialize the observer with the passed MSI bunch processor instance.
45
     *
46
     * @param \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface $msiBunchProcessor The MSI bunch processor instance
47
     * @param \TechDivision\Import\Observers\StateDetectorInterface|null           $stateDetector     The state detector instance to use
48
     */
49
    public function __construct(MsiBunchProcessorInterface $msiBunchProcessor, StateDetectorInterface $stateDetector = null)
50
    {
51
52
        // initialize the bunch processor instance
53
        $this->msiBunchProcessor = $msiBunchProcessor;
54
55
        // pass the state detector to the parent method
56
        parent::__construct($stateDetector);
57
    }
58
59
    /**
60
     * Return's the MSI bunch processor instance.
61
     *
62
     * @return \TechDivision\Import\Product\Msi\Services\MsiBunchProcessorInterface The MSI bunch processor instance
63
     */
64
    protected function getMsiBunchProcessor()
65
    {
66
        return $this->msiBunchProcessor;
67
    }
68
69
    /**
70
     * Process the observer's business logic.
71
     *
72
     * @return array The processed row
73
     */
74
    protected function process()
75
    {
76
77
        // load SKU and inventory source code
78
        $sku = $this->getValue(ColumnKeys::SKU);
79
        $sourceCode = $this->getValue(ColumnKeys::SOURCE_CODE);
80
81
        if ($product = $this->loadProduct($sku)) {
82
            $this->setLastEntityId($product[MemberNames::ENTITY_ID]);
83
        } else {
84
            $message = sprintf('Product with SKU "%s" can\'t be loaded to create source code "%s"', $sku, $sourceCode);
85
            // query whether or not we're in debug mode
86
            if (!$this->getSubject()->isStrictMode()) {
87
                $this->getSubject()->getSystemLogger()->warning($message);
88
                $this->mergeStatus(
89
                    array(
90
                        RegistryKeys::NO_STRICT_VALIDATIONS => array(
91
                            basename($this->getFilename()) => array(
92
                                $this->getLineNumber() => array(
93
                                    ColumnKeys::SKU => $message
94
                                )
95
                            )
96
                        )
97
                    )
98
                );
99
                return $this->getRow();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getRow() returns the type array which is incompatible with the return type mandated by TechDivision\Import\Prod...portObserver::process() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
100
            }
101
102
            throw new \Exception($this->appendExceptionSuffix($message));
103
        }
104
        // query whether or not, we've found a new SKU/source code combination => means we've found a inventory source item
105
        if ($this->hasSourceBeenProcessed($sku, $sourceCode)) {
106
            return;
107
        }
108
109
        // query whether or not the inventory source is with the given code is avaiable
110
        if ($this->hasInventorySource($sourceCode)) {
111
            // create the MSI inventory source item
112
            if ($this->hasChanges($inventorySourceItem = $this->initializeInventorySourceItem($this->prepareAttributes()))) {
113
                $this->persistInventorySourceItem($inventorySourceItem);
114
            }
115
116
            // finally, add the SKU + source code => source item ID mapping
117
            $this->addSkuSourceItemIdMapping($sku, $sourceCode);
118
        } else {
119
            // throw a new exception
120
            throw new \Exception(
121
                $this->appendExceptionSuffix(
122
                    sprintf('Can\'t load inventory source with code "%s"', $sourceCode)
123
                )
124
            );
125
        }
126
    }
127
128
    /**
129
     * Prepare the attributes of the entity that has to be persisted.
130
     *
131
     * @return array The prepared attributes
132
     */
133
    protected function prepareAttributes()
134
    {
135
136
        // load the MSI inventory source item values
137
        $sku = $this->getValue(ColumnKeys::SKU);
138
        $sourceCode = $this->getValue(ColumnKeys::SOURCE_CODE);
139
        $status = $this->castValueByBackendType(BackendTypeKeys::BACKEND_TYPE_INT, $this->getValue(ColumnKeys::STATUS));
140
        $quantity = $this->castValueByBackendType(BackendTypeKeys::BACKEND_TYPE_FLOAT, $this->getValue(ColumnKeys::QUANTITY));
141
142
        // return the prepared MSI inventory source item
143
        return $this->initializeEntity(
144
            array(
145
                MemberNames::SKU         => $sku,
146
                MemberNames::STATUS      => $status,
147
                MemberNames::SOURCE_CODE => $sourceCode,
148
                MemberNames::QUANTITY    => $quantity
149
            )
150
        );
151
    }
152
153
    /**
154
     * Initialize the MSI inventory source item with the passed attributes and returns an instance.
155
     *
156
     * @param array $attr The inventory source item attributes
157
     *
158
     * @return array The initialized inventory source item
159
     * @throws \RuntimeException Is thrown, if the attributes can not be initialized
160
     */
161
    protected function initializeInventorySourceItem(array $attr)
162
    {
163
        return $attr;
164
    }
165
166
    /**
167
     * Queries whether or not the inventory source with the passed code is available.
168
     *
169
     * @param string $sourceCode The code of the inventory source to query for
170
     *
171
     * @return boolean TRUE if the inventory source with the passed code is available, FALSE if not
172
     */
173
    protected function hasInventorySource($sourceCode)
174
    {
175
        return $this->getSubject()->hasInventorySource($sourceCode);
176
    }
177
178
    /**
179
     * Add the passed SKU/source code => source item ID mapping.
180
     *
181
     * @param string $sku        The SKU
182
     * @param string $sourceCode The source code
183
     *
184
     * @return void
185
     */
186
    protected function addSkuSourceItemIdMapping($sku, $sourceCode)
187
    {
188
        $this->getSubject()->addSkuSourceItemIdMapping($sku, $sourceCode);
189
    }
190
191
    /**
192
     * Persist's the passed inventory source item data.
193
     *
194
     * @param array $inventorySourceItem The inventory source item data to persist
195
     *
196
     * @return void
197
     */
198
    protected function persistInventorySourceItem($inventorySourceItem)
199
    {
200
        $this->getMsiBunchProcessor()->persistInventorySourceItem($inventorySourceItem);
201
    }
202
203
    /**
204
     * Load's and return's the product with the passed SKU.
205
     *
206
     * @param string $sku The SKU of the product to load
207
     *
208
     * @return array The product
209
     */
210
    protected function loadProduct($sku)
211
    {
212
        return $this->getMsiBunchProcessor()->loadProduct($sku);
213
    }
214
215
    /**
216
     * Set's the ID of the product that has been created recently.
217
     *
218
     * @param string $lastEntityId The entity ID
219
     *
220
     * @return void
221
     */
222
    protected function setLastEntityId($lastEntityId)
223
    {
224
        $this->getSubject()->setLastEntityId($lastEntityId);
225
    }
226
}
227