PluginProbe
PostNL for WooCommerce / 4.4.0
PostNL for WooCommerce v4.4.0
5.9.12 5.9.11 5.9.10 5.9.9 5.9.8 5.9.7 5.9.6 trunk 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 3.1.4 3.1.5 3.1.6 3.1.7 4.0.0 4.0.1 4.0.2 4.3.2 4.3.3 4.4.0 4.4.1 All 72 releases
woo-postnl / vendor / myparcelnl / sdk / src / Services / ConsignmentEncode.php

ConsignmentEncode.php in PostNL for WooCommerce 4.4.0, at vendor/myparcelnl/sdk/src/Services/ConsignmentEncode.php

344 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php declare(strict_types=1);
2 /**
3 * If you want to add improvements, please create a fork in our GitHub:
4 * https://github.com/myparcelnl
5 *
6 * @author Reindert Vetter <[email protected]>
7 * @copyright 2010-2020 MyParcel
8 * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL
9 * @link https://github.com/myparcelnl/sdk
10 * @since File available since Release v1.1.7
11 */
12
13 namespace MyParcelNL\Sdk\src\Services;
14
15 use InvalidArgumentException;
16 use MyParcelNL\Sdk\src\Exception\MissingFieldException;
17 use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment;
18 use MyParcelNL\Sdk\src\Model\MyParcelCustomsItem;
19 use MyParcelNL\Sdk\src\Support\Arr;
20
21 class ConsignmentEncode
22 {
23 /**
24 * @var array
25 */
26 private $consignmentEncoded = [];
27
28 /**
29 * @var AbstractConsignment[]
30 */
31 private $consignments;
32
33 public function __construct($consignments)
34 {
35 $this->consignments = $consignments;
36 }
37
38 /**
39 * Encode all the data before sending it to MyParcel
40 *
41 * @return array
42 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
43 * @throws \Exception
44 */
45 public function apiEncode(): array
46 {
47 $this->encodeBase()
48 ->encodeStreet();
49
50 $this->consignmentEncoded = self::encodeExtraOptions(
51 $this->consignmentEncoded,
52 Arr::first($this->consignments)
53 );
54 $this->encodeDeliveryType()
55 ->encodePickup()
56 ->encodePhysicalProperties()
57 ->encodeCdCountry()
58 ->encodeMultiCollo();
59
60 return $this->consignmentEncoded;
61 }
62
63 /**
64 * @param array $consignmentEncoded
65 * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment
66 *
67 * @return array
68 */
69 public static function encodeExtraOptions(array $consignmentEncoded, AbstractConsignment $consignment): array
70 {
71 $consignmentEncoded = array_merge_recursive(
72 $consignmentEncoded,
73 [
74 'options' => [
75 'package_type' => $consignment->getPackageType(AbstractConsignment::DEFAULT_PACKAGE_TYPE),
76 'label_description' => $consignment->getLabelDescription(),
77 'only_recipient' => (int) $consignment->isOnlyRecipient(),
78 'signature' => (int) $consignment->isSignature(),
79 'return' => (int) $consignment->isReturn(),
80 ],
81 ]
82 );
83
84 if ($consignment->isEuCountry()) {
85 $consignmentEncoded['options']['large_format'] = (int) $consignment->isLargeFormat();
86 }
87
88 if ($consignment->getCountry() == AbstractConsignment::CC_NL && $consignment->hasAgeCheck()) {
89 $consignmentEncoded['options']['age_check'] = 1;
90 $consignmentEncoded['options']['only_recipient'] = 1;
91 $consignmentEncoded['options']['signature'] = 1;
92 } elseif ($consignment->hasAgeCheck()) {
93 throw new InvalidArgumentException('The age check is not possible with an EU shipment or world shipment');
94 }
95
96 if ($consignment->getDeliveryDate()) {
97 $consignmentEncoded['options']['delivery_date'] = $consignment->getDeliveryDate();
98 }
99
100 if ($consignment->getInsurance() > 1) {
101 $consignmentEncoded['options']['insurance'] = [
102 'amount' => (int) $consignment->getInsurance() * 100,
103 'currency' => 'EUR',
104 ];
105 }
106
107 return $consignmentEncoded;
108 }
109
110 /**
111 * @return self
112 */
113 private function encodeDeliveryType(): self
114 {
115 /** @var AbstractConsignment $consignment */
116 $consignment = Arr::first($this->consignments);
117 $this->consignmentEncoded['options']['delivery_type'] = $consignment->getDeliveryType();
118
119 return $this;
120 }
121
122 /**
123 * @return self
124 */
125 private function encodeBase(): self
126 {
127 /** @var AbstractConsignment $consignment */
128 $consignment = Arr::first($this->consignments);
129
130 $this->consignmentEncoded = [
131 'recipient' => [
132 'cc' => $consignment->getCountry(),
133 'person' => $consignment->getPerson(),
134 'postal_code' => $consignment->getPostalCode(),
135 'city' => (string) $consignment->getCity(),
136 'email' => (string) $consignment->getEmail(),
137 'phone' => (string) $consignment->getPhone(),
138 ],
139 'carrier' => $consignment->getCarrierId(),
140 ];
141
142 if ($consignment->getReferenceId()) {
143 $this->consignmentEncoded['reference_identifier'] = $consignment->getReferenceId();
144 }
145
146 if ($consignment->getCompany()) {
147 $this->consignmentEncoded['recipient']['company'] = $consignment->getCompany();
148 }
149
150 return $this;
151 }
152
153 /**
154 * @return $this
155 */
156 private function encodeStreet()
157 {
158 $consignment = Arr::first($this->consignments);
159 $this->consignmentEncoded = $consignment->encodeStreet($this->consignmentEncoded);
160
161 return $this;
162 }
163
164 /**
165 * Set pickup address
166 * @return $this
167 */
168 private function encodePickup()
169 {
170 /** @var AbstractConsignment $consignment */
171 $consignment = Arr::first($this->consignments);
172 if (
173 $consignment->getPickupPostalCode() !== null &&
174 $consignment->getPickupStreet() !== null &&
175 $consignment->getPickupCity() !== null &&
176 $consignment->getPickupNumber() !== null &&
177 $consignment->getPickupLocationName() !== null
178 ) {
179 $this->consignmentEncoded['pickup'] = [
180 'cc' => $consignment->getPickupCountry(),
181 'postal_code' => $consignment->getPickupPostalCode(),
182 'street' => $consignment->getPickupStreet(),
183 'city' => $consignment->getPickupCity(),
184 'number' => $consignment->getPickupNumber(),
185 'location_name' => $consignment->getPickupLocationName(),
186 'location_code' => $consignment->getPickupLocationCode(),
187 'retail_network_id' => $consignment->getRetailNetworkId(),
188 ];
189 }
190
191 $this->consignmentEncoded['general_settings']['save_recipient_address'] = $this->normalizeAutoSaveRecipientAddress($consignment);
192 $this->consignmentEncoded['general_settings']['disable_auto_detect_pickup'] = $this->normalizeAutoDetectPickup($consignment);
193
194 return $this;
195 }
196
197 /**
198 * @return $this
199 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
200 */
201 private function encodePhysicalProperties()
202 {
203 $consignment = Arr::first($this->consignments);
204 if (empty($consignment->getPhysicalProperties()) && $consignment->getPackageType() != AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP) {
205 return $this;
206 }
207 if ($consignment->getPackageType() == AbstractConsignment::PACKAGE_TYPE_DIGITAL_STAMP && ! isset($consignment->getPhysicalProperties()['weight'])) {
208 throw new MissingFieldException('Weight in physical properties must be set for digital stamp shipments.');
209 }
210
211 $this->consignmentEncoded['physical_properties'] = $consignment->getPhysicalProperties();
212
213 return $this;
214 }
215
216 /**
217 * @return $this
218 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
219 */
220 private function encodeCdCountry()
221 {
222 /**
223 * @var \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment
224 */
225 $consignment = Arr::first($this->consignments);
226 if ($consignment->isEuCountry()) {
227 return $this;
228 }
229
230 $this->validateCdConsignment($consignment);
231
232 $items = [];
233 foreach ($consignment->getItems() as $item) {
234 $items[] = $this->encodeCdCountryItem($item);
235 }
236
237 if (empty($consignment->getPhysicalProperties())) {
238 $consignment->setPhysicalProperties(['weight' => $consignment->getTotalWeight()]);
239 }
240
241 $customsDeclaration = [
242 'customs_declaration' => [
243 'contents' => $consignment->getContents() ?? 1,
244 'weight' => $consignment->getTotalWeight(),
245 'items' => $items,
246 'invoice' => $consignment->getInvoice() ?? '',
247 ],
248 'physical_properties' => $consignment->getPhysicalProperties(),
249 ];
250
251 $this->consignmentEncoded = Arr::arrayMergeRecursiveDistinct(
252 $this->consignmentEncoded,
253 $customsDeclaration
254 );
255
256 return $this;
257 }
258
259 /**
260 * Encode product for the request
261 *
262 * @return array
263 * @var string $currency
264 * @var MyParcelCustomsItem $customsItem
265 */
266 private function encodeCdCountryItem($customsItem, $currency = 'EUR')
267 {
268 $item = [
269 'description' => $customsItem->getDescription(),
270 'amount' => $customsItem->getAmount(),
271 'weight' => $customsItem->getWeight(),
272 'classification' => $customsItem->getClassification(),
273 'country' => $customsItem->getCountry(),
274 'item_value' => [
275 'amount' => $customsItem->getItemValue(),
276 'currency' => $currency,
277 ],
278 ];
279
280 return $item;
281 }
282
283 /**
284 * @param AbstractConsignment $consignment
285 *
286 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
287 */
288 private function validateCdConsignment(AbstractConsignment $consignment)
289 {
290 if (empty($consignment->getItems())) {
291 throw new MissingFieldException('Product data must be set for international MyParcel shipments. Use addItem().');
292 }
293
294 if ($consignment->getPackageType() !== AbstractConsignment::PACKAGE_TYPE_PACKAGE && $consignment->getPackageType() !== AbstractConsignment::PACKAGE_TYPE_LETTER) {
295 throw new MissingFieldException('For international shipments, package_type must be 1 (normal package) or 3 (letter).');
296 }
297
298 if (empty($consignment->getInvoice())) {
299 throw new MissingFieldException('Invoice id is required for international shipments. Use setInvoice().');
300 }
301 }
302
303 /**
304 * @return ConsignmentEncode
305 * @throws \Exception
306 */
307 private function encodeMultiCollo()
308 {
309 /** @var AbstractConsignment $first */
310 $first = Arr::first($this->consignments);
311 if (count($this->consignments) > 1 && ! $first->isPartOfMultiCollo()) {
312 throw new \Exception("Can not encode multi collo with this consignment.");
313 }
314
315 $secondaryShipments = $this->consignments;
316 Arr::forget($secondaryShipments, 0);
317 foreach ($secondaryShipments as $secondaryShipment) {
318 $this->consignmentEncoded['secondary_shipments'][] = (object) ['reference_identifier' => $secondaryShipment->getReferenceId()];
319 }
320
321 return $this;
322 }
323
324 /**
325 * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment
326 *
327 * @return int
328 */
329 private function normalizeAutoDetectPickup(AbstractConsignment $consignment): int
330 {
331 return $consignment->isAutoDetectPickup() ? 0 : 1;
332 }
333
334 /**
335 * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment $consignment
336 *
337 * @return int
338 */
339 private function normalizeAutoSaveRecipientAddress(AbstractConsignment $consignment): int
340 {
341 return (int) $consignment->isSaveRecipientAddress();
342 }
343 }
344