PluginProbe
PostNL for WooCommerce / 4.0.0
PostNL for WooCommerce v4.0.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 / includes / vendor / myparcelnl / sdk / src / Helper / MyParcelCollection.php

MyParcelCollection.php in PostNL for WooCommerce 4.0.0, at includes/vendor/myparcelnl/sdk/src/Helper/MyParcelCollection.php

941 lines 28.4 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 * Stores all data to communicate with the MyParcel API
4 *
5 * If you want to add improvements, please create a fork in our GitHub:
6 * https://github.com/myparcelnl
7 *
8 * @author Reindert Vetter <[email protected]>
9 * @copyright 2010-2020 MyParcel
10 * @license http://creativecommons.org/licenses/by-nc-nd/3.0/nl/deed.en_US CC BY-NC-ND 3.0 NL
11 * @link https://github.com/myparcelnl/sdk
12 * @since File available since Release v0.1.0
13 */
14
15 namespace MyParcelNL\Sdk\src\Helper;
16
17 use Exception;
18 use http\Exception\BadMethodCallException;
19 use InvalidArgumentException;
20 use MyParcelNL\Sdk\src\Adapter\ConsignmentAdapter;
21 use MyParcelNL\Sdk\src\Exception\ApiException;
22 use MyParcelNL\Sdk\src\Exception\MissingFieldException;
23 use MyParcelNL\Sdk\src\Factory\ConsignmentFactory;
24 use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment;
25 use MyParcelNL\Sdk\src\Model\MyParcelRequest;
26 use MyParcelNL\Sdk\src\Services\CollectionEncode;
27 use MyParcelNL\Sdk\src\Services\ConsignmentEncode;
28 use MyParcelNL\Sdk\src\Support\Arr;
29 use MyParcelNL\Sdk\src\Support\Collection;
30 use MyParcelNL\Sdk\src\Support\Str;
31
32 /**
33 * Stores all data to communicate with the MyParcel API
34 *
35 * Class MyParcelCollection
36 */
37 class MyParcelCollection extends Collection
38 {
39 const PREFIX_PDF_FILENAME = 'myparcel-label-';
40 const DEFAULT_A4_POSITION = 1;
41
42 /**
43 * @var string
44 */
45 private $paper_size = 'A6';
46
47 /**
48 * The position of the label on the paper.
49 * pattern: [1 - 4]
50 * example: 1. (top-left)
51 * 2. (top-right)
52 * 3. (bottom-left)
53 * 4. (bottom-right)
54 *
55 * @var string
56 */
57 private $label_position;
58
59 /**
60 * Link to download the PDF
61 *
62 * @var string
63 */
64 private $label_link;
65
66 /**
67 * Label in PDF format
68 *
69 * @var string
70 */
71 private $label_pdf;
72
73 /**
74 * @var string
75 */
76 private static $user_agent;
77
78 /**
79 * @param bool $keepKeys
80 *
81 * @return AbstractConsignment[]
82 */
83 public function getConsignments($keepKeys = true): array
84 {
85 if ($keepKeys) {
86 return $this->items;
87 }
88
89 return array_values($this->items);
90 }
91
92 /**
93 * Get one consignment
94 * @return mixed
95 *
96 * @throws BadMethodCallException
97 */
98 public function getOneConsignment()
99 {
100 if ($this->count() > 1) {
101 throw new BadMethodCallException('Can\'t run getOneConsignment(): Multiple items found');
102 }
103
104 return $this->first();
105 }
106
107 /**
108 * @param string|null $id
109 *
110 * @return MyParcelCollection
111 * @throws InvalidArgumentException
112 */
113 public function getConsignmentsByReferenceId($id): MyParcelCollection
114 {
115 if ($id === null) {
116 throw new InvalidArgumentException('Can\'t run getConsignmentsByReferenceId() because referenceId can\'t be null');
117 }
118
119 if ($this->count() === 1) {
120 return new static($this->items);
121 }
122
123 return $this->where('reference_identifier', $id);
124 }
125
126 /**
127 * @param $groupId
128 *
129 * @return MyParcelCollection
130 */
131 public function getConsignmentsByReferenceIdGroup($groupId): MyParcelCollection
132 {
133 return $this->findByReferenceIdGroup($groupId);
134 }
135
136 /**
137 * This is deprecated because there may be multiple consignments with the same reference id
138 *
139 * @param $id
140 *
141 * @return mixed
142 * @throws Exception
143 * @deprecated Use getConsignmentsByReferenceId()->first() instead
144 *
145 */
146 public function getConsignmentByReferenceId($id)
147 {
148 return $this->getConsignmentsByReferenceId($id)->first();
149 }
150
151 /**
152 * @param int $id
153 *
154 * @return AbstractConsignment
155 */
156 public function getConsignmentByApiId($id)
157 {
158 return $this->where('consignment_id', $id)->first();
159 }
160
161 /**
162 * @return string
163 *
164 * this is used by third parties to access the label_pdf variable.
165 */
166 public function getLabelPdf()
167 {
168 return $this->label_pdf;
169 }
170
171 /**
172 * @return string
173 */
174 public function getLinkOfLabels()
175 {
176 return $this->label_link;
177 }
178
179 /**
180 * @param AbstractConsignment $consignment
181 *
182 * @return $this
183 * @throws MissingFieldException
184 */
185 public function addConsignment(AbstractConsignment $consignment)
186 {
187 if ($consignment->getApiKey() === null) {
188 throw new MissingFieldException('First set the API key with setApiKey() before running addConsignment()');
189 }
190
191 $consignment->validate();
192
193 $this->push($consignment);
194
195 return $this;
196 }
197
198 /**
199 * @param int[] $ids
200 * @param string $apiKey
201 *
202 * @return self
203 * @throws Exception
204 */
205 public function addConsignmentByConsignmentIds($ids, $apiKey)
206 {
207 foreach ($ids as $consignmentId) {
208 $consignment = (new AbstractConsignment())
209 ->setApiKey($apiKey)
210 ->setConsignmentId($consignmentId);
211
212 $this->addConsignment($consignment);
213 }
214
215 return $this;
216 }
217
218 /**
219 * @param string[] $ids
220 * @param string $apiKey
221 *
222 * @return self
223 * @throws Exception
224 */
225 public function addConsignmentByReferenceIds($ids, $apiKey)
226 {
227 foreach ($ids as $referenceId) {
228 $consignment = (new AbstractConsignment())
229 ->setApiKey($apiKey)
230 ->setReferenceId($referenceId);
231
232 $this->addConsignment($consignment);
233 }
234
235 return $this;
236 }
237
238 /**
239 * @param AbstractConsignment $consignment
240 * @param $amount
241 *
242 * @return MyParcelCollection
243 */
244 public function addMultiCollo(AbstractConsignment $consignment, $amount): self
245 {
246 $i = 1;
247
248 if ($amount > 1) {
249 $consignment->setMultiCollo();
250 }
251
252 if ($consignment->isPartOfMultiCollo() && null == $consignment->getReferenceId()) {
253 $consignment->setReferenceId('random_multi_collo_' . uniqid());
254 }
255
256 while ($i <= $amount) {
257 $this->push($consignment);
258 $i++;
259 }
260
261 return $this;
262 }
263
264 /**
265 * Create concepts in MyParcel.
266 *
267 * @return $this
268 * @throws MissingFieldException
269 * @throws ApiException
270 */
271 public function createConcepts(): self
272 {
273 $newConsignments = $this->where('consignment_id', '!=', null)->toArray();
274 $this->addMissingReferenceId();
275
276 /* @var $consignments MyParcelCollection */
277 foreach ($this->where('consignment_id', null)->groupBy('api_key') as $consignments) {
278 $data = (new CollectionEncode($consignments))->encode();
279 $request = (new MyParcelRequest())
280 ->setUserAgent($this->getUserAgent())
281 ->setRequestParameters(
282 $consignments->first()->api_key,
283 $data,
284 MyParcelRequest::REQUEST_HEADER_SHIPMENT
285 )
286 ->sendRequest();
287
288 /**
289 * Loop through the returned ids and add each consignment id to a consignment.
290 */
291 foreach ($request->getResult('data.ids') as $responseShipment) {
292 $consignments = $this->getConsignmentsByReferenceId($responseShipment['reference_identifier']);
293 $consignment = clone $consignments->pop();
294 $newConsignments[] = $consignment->setConsignmentId($responseShipment['id']);
295 }
296 }
297
298 $this->items = $newConsignments;
299
300 return $this;
301 }
302
303 /**
304 * Label prepare wil be active from x number of orders
305 *
306 * @param int $numberOfShipments
307 *
308 * @return bool
309 */
310 public function useLabelPrepare(int $numberOfShipments): bool
311 {
312 return $numberOfShipments > MyParcelRequest::SHIPMENT_LABEL_PREPARE_ACTIVE_FROM;
313 }
314
315 /**
316 * Delete concepts in MyParcel
317 *
318 * @return $this
319 * @throws Exception
320 */
321 public function deleteConcepts()
322 {
323 /* @var $consignments AbstractConsignment[] */
324 foreach ($this->groupBy('api_key')->where('consignment_id', '!=', null) as $key => $consignments) {
325 foreach ($consignments as $consignment) {
326 (new MyParcelRequest())
327 ->setUserAgent($this->getUserAgent())
328 ->setRequestParameters(
329 $key,
330 (string) $consignment->getConsignmentId(),
331 MyParcelRequest::REQUEST_HEADER_DELETE
332 )
333 ->sendRequest('DELETE');
334 }
335 }
336
337 return $this;
338 }
339
340 /**
341 * Get all current data
342 *
343 * Set id and run this function to update all the information about this shipment
344 *
345 * @param int $size
346 *
347 * @return $this
348 * @throws Exception
349 */
350 public function setLatestData($size = 300)
351 {
352 $myParcelRequest = new MyParcelRequest();
353 $params = $myParcelRequest->getLatestDataParams($size, $this, $key);
354
355 $request = $myParcelRequest
356 ->setUserAgent($this->getUserAgent())
357 ->setRequestParameters(
358 $key,
359 $params,
360 MyParcelRequest::REQUEST_HEADER_RETRIEVE_SHIPMENT
361 )
362 ->sendRequest('GET');
363
364 if ($request->getResult() === null) {
365 throw new ApiException('Unknown Error in MyParcel API response');
366 }
367
368 $result = $request->getResult('data.shipments');
369 $newCollection = $this->getNewCollectionFromResult($result);
370
371 $this->items = $newCollection->sortByCollection($this)->items;
372
373 return $this;
374 }
375
376 /**
377 * Get all the information about the last created shipments
378 *
379 * @param $key
380 * @param int $size
381 *
382 * @return $this
383 * @throws ApiException
384 * @throws MissingFieldException
385 * @throws Exception
386 * @deprecated use MyParcelCollection::query($key, ['size' => 300]) instead
387 */
388 public function setLatestDataWithoutIds($key, $size = 300)
389 {
390 $params = ['size' => $size];
391
392 return self::query($key, $params);
393 }
394
395 /**
396 * Get link of labels
397 *
398 * @param int $positions The position of the label on an A4 sheet. Set to false to create an A6 sheet.
399 * You can specify multiple positions by using an array. E.g. [2,3,4]. If you do
400 * not specify an array, but specify a number, the following labels will fill the
401 * ascending positions. Positioning is only applied on the first page with labels.
402 * All subsequent pages will use the default positioning [1,2,3,4].
403 *
404 * @return $this
405 * @throws Exception
406 */
407 public function setLinkOfLabels($positions = self::DEFAULT_A4_POSITION)
408 {
409 $urlLocation = 'pdfs';
410
411 /** If $positions is not false, set paper size to A4 */
412 $this
413 ->createConcepts()
414 ->setLabelFormat($positions);
415
416 $conceptIds = $this->getConsignmentIds($key);
417 $requestType = MyParcelRequest::REQUEST_TYPE_RETRIEVE_LABEL;
418 if ($this->useLabelPrepare(count($conceptIds))) {
419 $requestType = MyParcelRequest::REQUEST_TYPE_RETRIEVE_PREPARED_LABEL;
420 $urlLocation = 'pdf';
421 }
422
423 if ($key) {
424 $request = (new MyParcelRequest())
425 ->setUserAgent($this->getUserAgent())
426 ->setRequestParameters(
427 $key,
428 implode(';', $conceptIds) . '/' . $this->getRequestBody(),
429 MyParcelRequest::REQUEST_HEADER_RETRIEVE_LABEL_LINK
430 )
431 ->sendRequest('GET', $requestType);
432
433 $this->label_link = MyParcelRequest::REQUEST_URL . $request->getResult("data.$urlLocation.url");
434 }
435
436 $this->setLatestData();
437
438 return $this;
439 }
440
441 /**
442 * Receive label PDF
443 *
444 * After setPdfOfLabels() apiId and barcode is present
445 *
446 * @param int $positions The position of the label on an A4 sheet. You can specify multiple positions by
447 * using an array. E.g. [2,3,4]. If you do not specify an array, but specify a
448 * number, the following labels will fill the ascending positions. Positioning is
449 * only applied on the first page with labels. All subsequent pages will use the
450 * default positioning [1,2,3,4].
451 *
452 * @return $this
453 * @throws Exception
454 */
455 public function setPdfOfLabels($positions = self::DEFAULT_A4_POSITION)
456 {
457 /** If $positions is not false, set paper size to A4 */
458 $this
459 ->createConcepts()
460 ->setLabelFormat($positions);
461 $conceptIds = $this->getConsignmentIds($key);
462
463 if ($key) {
464 $request = (new MyParcelRequest())
465 ->setUserAgent($this->getUserAgent())
466 ->setRequestParameters(
467 $key,
468 implode(';', $conceptIds) . '/' . $this->getRequestBody(),
469 MyParcelRequest::REQUEST_HEADER_RETRIEVE_LABEL_PDF
470 )
471 ->sendRequest('GET', MyParcelRequest::REQUEST_TYPE_RETRIEVE_LABEL);
472
473 $this->label_pdf = $request->getResult();
474 }
475 $this->setLatestData();
476
477 return $this;
478 }
479
480 /**
481 * Download labels
482 *
483 * @param bool $inline_download
484 *
485 * @return void
486 * @throws Exception
487 */
488 public function downloadPdfOfLabels($inline_download = false)
489 {
490 if ($this->label_pdf == null) {
491 throw new MissingFieldException('First set label_pdf key with setPdfOfLabels() before running downloadPdfOfLabels()');
492 }
493
494 header('Content-Type: application/pdf');
495 header('Content-Length: ' . strlen($this->label_pdf));
496 header('Content-disposition: ' . ($inline_download === true ? "inline" : "attachment") . '; filename="' . self::PREFIX_PDF_FILENAME . gmdate('Y-M-d H-i-s') . '.pdf"');
497 header('Cache-Control: public, must-revalidate, max-age=0');
498 header('Pragma: public');
499 header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
500 header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
501 echo $this->label_pdf;
502 exit;
503 }
504
505 /**
506 * Send return label to customer. The customer can pay and download the label.
507 *
508 * @param bool $sendMail
509 * @param \Closure|null $modifier
510 *
511 * @return $this
512 * @throws \MyParcelNL\Sdk\src\Exception\ApiException
513 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
514 */
515 public function generateReturnConsignments(bool $sendMail, \Closure $modifier = null): self
516 {
517 // Be sure consignments are created
518 $this->createConcepts();
519
520 $parentConsignments = $this->getConsignments(false);
521 $returnConsignments = $this->getReturnConsignments($parentConsignments, $modifier);
522
523 $data = $this->apiEncodeReturnShipments($returnConsignments);
524 $apiKey = $returnConsignments[0]->getApiKey();
525 $requestType = MyParcelRequest::REQUEST_TYPE_SHIPMENTS;
526
527 $request = (new MyParcelRequest())
528 ->setUserAgent($this->getUserAgent())
529 ->setRequestParameters(
530 $apiKey,
531 $data,
532 MyParcelRequest::REQUEST_HEADER_RETURN
533 )
534 ->setQuery(['send_return_mail' => (int) $sendMail])
535 ->sendRequest('POST', $requestType);
536
537 $result = $request->getResult();
538
539 if ($result === null) {
540 throw new ApiException('Unknown Error in MyParcel API response');
541 }
542
543 $returnIds = Arr::pluck(Arr::get($result, 'data.ids'), 'id');
544 if (! $returnIds || count($returnIds) < 1) {
545 throw new InvalidArgumentException('Can\'t send return label to customer. Please create an issue on GitHub or contact MyParcel; [email protected]. Note this request body: ' . $data);
546 }
547
548 $returnConsignments = (new MyParcelCollection())
549 ->addConsignmentByConsignmentIds($returnIds, $apiKey)
550 ->setLatestData();
551
552 $this->items = Arr::mergeAfterEachOther($parentConsignments, $returnConsignments->toArray());
553
554 return $this;
555 }
556
557 /**
558 * Send return label to customer. The customer can pay and download the label.
559 *
560 * @return $this
561 * @throws ApiException
562 * @throws MissingFieldException
563 * @deprecated Use generateReturnConsignments instead
564 */
565 public function sendReturnLabelMails(): self
566 {
567 return $this->generateReturnConsignments(true);
568 }
569
570 /**
571 * Get all consignment ids
572 *
573 * @param string|null $key
574 *
575 * @return array|null
576 */
577 public function getConsignmentIds(string &$key = null): ?array
578 {
579 $conceptIds = [];
580 /** @var AbstractConsignment $consignment */
581 foreach ($this->where('consignment_id', '!=', null) as $consignment) {
582 $conceptIds[] = $consignment->getConsignmentId();
583 $key = $consignment->getApiKey();
584 }
585
586 if (empty($conceptIds)) {
587 return null;
588 }
589
590 return $conceptIds;
591 }
592
593 /**
594 * @inheritdoc
595 */
596 public function getRequestBody()
597 {
598 $body = $this->paper_size == 'A4' ? '?format=A4&positions=' . $this->label_position : '?format=A6';
599
600 return $body;
601 }
602
603 /**
604 * @return string
605 */
606 public function getUserAgent()
607 {
608 return $this::$user_agent;
609 }
610
611 /**
612 * @param string $platform
613 * @param string|null $version
614 *
615 * @return self
616 * @internal param string $user_agent
617 * @deprecated Use setCustomUserAgent instead
618 */
619 public function setUserAgent(string $platform, string $version = null): self
620 {
621 $this::$user_agent = 'MyParcel-' . $platform;
622 if ($version !== null) {
623 $this::$user_agent .= '/' . str_replace('v', '', $version);
624 }
625
626 return $this;
627 }
628
629 /**
630 * @param array $userAgentMap
631 *
632 * @return self
633 */
634 public function setUserAgents(array $userAgentMap): self
635 {
636 $userAgents = [];
637
638 foreach ($userAgentMap as $key => $value) {
639 if (Str::startsWith($value, 'v')) {
640 $value = str_replace('v', '', $value);
641 }
642
643 $userAgents[] = $key . '/' . $value;
644 }
645
646 self::$user_agent = implode(' ', $userAgents);
647
648 return $this;
649 }
650
651 /**
652 * Clear this collection
653 */
654 public function clearConsignmentsCollection()
655 {
656 $this->items = [];
657 }
658
659 /**
660 * To search and filter consignments by certain values
661 *
662 * @param string $apiKey
663 * @param mixed $parameters May be an array or object containing properties.
664 * If query_data is an array, it may be a simple one-dimensional structure,
665 * or an array of arrays (which in turn may contain other arrays).
666 * If query_data is an object, then only public properties will be incorporated
667 * into the result.
668 *
669 * @return \MyParcelNL\Sdk\src\Helper\MyParcelCollection
670 * @throws \MyParcelNL\Sdk\src\Exception\ApiException
671 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
672 * @throws \Exception
673 */
674 public static function query(string $apiKey, $parameters): MyParcelCollection
675 {
676 $collection = new static();
677
678 // The field `size` is required to prevent bugs. Think carefully about what
679 // the maximum size should be in your use case. If you want to pick up all
680 // open consignments for example, you would probably want to adjust size to 300.
681 if (empty($parameters['size'])) {
682 throw new MissingFieldException('Field "size" is required.');
683 }
684
685 $request = (new MyParcelRequest())
686 ->setRequestParameters(
687 $apiKey,
688 null,
689 MyParcelRequest::REQUEST_HEADER_RETRIEVE_SHIPMENT
690 )
691 ->setQuery($parameters)
692 ->sendRequest('GET');
693
694 if ($request->getResult() === null) {
695 throw new ApiException('Unknown error in MyParcel API response');
696 }
697
698 foreach ($request->getResult()['data']['shipments'] as $shipment) {
699 $consignmentAdapter = new ConsignmentAdapter($shipment, (ConsignmentFactory::createByCarrierId($shipment['carrier_id'])->setApiKey($apiKey)));
700 $collection->addConsignment($consignmentAdapter->getConsignment());
701 }
702
703 return $collection;
704 }
705
706 /**
707 * @param int $id
708 * @param string $apiKey
709 *
710 * @return MyParcelCollection
711 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
712 */
713 public static function find(int $id, string $apiKey): MyParcelCollection
714 {
715 return self::findMany([$id], $apiKey);
716 }
717
718 /**
719 * @param array $consignmentIds
720 * @param string $apiKey
721 *
722 * @return MyParcelCollection
723 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
724 */
725 public static function findMany(array $consignmentIds, string $apiKey): MyParcelCollection
726 {
727 $collection = new static();
728
729 foreach ($consignmentIds as $id) {
730 $consignment = new AbstractConsignment();
731 $consignment->setConsignmentId((int) $id);
732 $consignment->setApiKey($apiKey);
733
734 $collection->addConsignment($consignment);
735 }
736
737 $collection->setLatestData();
738
739 return $collection;
740 }
741
742 /**
743 * @param string $id
744 * @param string $apiKey
745 *
746 * @return MyParcelCollection
747 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
748 */
749 public static function findByReferenceId(string $id, string $apiKey): MyParcelCollection
750 {
751 return self::findManyByReferenceId([$id], $apiKey);
752 }
753
754 /**
755 * @param array $referenceIds
756 * @param string $apiKey
757 *
758 * @return MyParcelCollection
759 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
760 */
761 public static function findManyByReferenceId(array $referenceIds, string $apiKey): MyParcelCollection
762 {
763 $collection = new static();
764
765 foreach ($referenceIds as $id) {
766 $consignment = new AbstractConsignment();
767 $consignment->setReferenceId($id);
768 $consignment->setApiKey($apiKey);
769
770 $collection->addConsignment($consignment);
771 }
772
773 $collection->setLatestData();
774
775 return $collection;
776 }
777
778 /**
779 * @param \MyParcelNL\Sdk\src\Helper\MyParcelCollection|\MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment[] $sortedCollection
780 *
781 * @return $this
782 */
783 public function sortByCollection(MyParcelCollection $sortedCollection): MyParcelCollection
784 {
785 $result = new MyParcelCollection();
786
787 foreach ($sortedCollection as $sorted) {
788 $consignment = $this->where('consignment_id', $sorted->getConsignmentId())->first();
789
790 if ($consignment) {
791 $result[] = $consignment;
792 }
793 }
794
795 $leftItems = $this->whereNotIn('consignment_id', $result->getConsignmentIds());
796
797 return $result->merge($leftItems);
798 }
799
800 /**
801 * Set label format settings The position of the label on an A4 sheet. You can specify multiple positions by
802 * using an array. E.g. [2,3,4]. If you do not specify an array, but specify a
803 * number, the following labels will fill the ascending positions. Positioning is
804 * only applied on the first page with labels. All subsequent pages will use the
805 * default positioning [1,2,3,4].
806 *
807 * @param int|array|null $positions
808 *
809 * @return $this
810 */
811 private function setLabelFormat($positions)
812 {
813 /** If $positions is not false, set paper size to A4 */
814 if (is_numeric($positions)) {
815 /** Generating positions for A4 paper */
816 $this->paper_size = 'A4';
817 $this->label_position = LabelHelper::getPositions($positions);
818 } elseif (is_array($positions)) {
819 /** Set positions for A4 paper */
820 $this->paper_size = 'A4';
821 $this->label_position = implode(';', $positions);
822 } else {
823 /** Set paper size to A6 */
824 $this->paper_size = 'A6';
825 $this->label_position = null;
826 }
827
828 return $this;
829 }
830
831 /**
832 * Encode ReturnShipment to send to MyParcel
833 *
834 * @param \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment[] $consignments
835 *
836 * @return string
837 */
838 private function apiEncodeReturnShipments(array $consignments): string
839 {
840 $data = [];
841
842 foreach ($consignments as $consignment) {
843 $shipment = [
844 'parent' => $consignment->getConsignmentId(),
845 'carrier' => $consignment->getCarrierId(),
846 'email' => $consignment->getEmail(),
847 'name' => $consignment->getPerson(),
848 ];
849
850 $shipment = ConsignmentEncode::encodeExtraOptions($shipment, $consignment);
851
852 $data['data']['return_shipments'][] = $shipment;
853 }
854
855 return json_encode($data);
856 }
857
858 /**
859 * @param $result
860 *
861 * @return MyParcelCollection
862 * @throws Exception
863 */
864 private function getNewCollectionFromResult($result)
865 {
866 $newCollection = new static();
867 /** @var AbstractConsignment $consignment */
868 $consignment = $this->first();
869 $apiKey = $consignment->getApiKey();
870
871 foreach ($result as $shipment) {
872 $consignment = ConsignmentFactory::createByCarrierId($shipment['carrier_id'])->setApiKey($apiKey);
873 $consignmentAdapter = new ConsignmentAdapter($shipment, $consignment);
874 $isMultiCollo = ! empty($shipment['secondary_shipments']);
875 $newCollection->addConsignment($consignmentAdapter->getConsignment()->setMultiCollo($isMultiCollo));
876
877 foreach ($shipment['secondary_shipments'] as $secondaryShipment) {
878 $secondaryShipment = Arr::arrayMergeRecursiveDistinct($shipment, $secondaryShipment);
879 $consignment = ConsignmentFactory::createByCarrierId($shipment['carrier_id'])->setApiKey($apiKey);
880 $consignmentAdapter = new ConsignmentAdapter($secondaryShipment, $consignment);
881 $newCollection->addConsignment($consignmentAdapter->getConsignment()->setMultiCollo($isMultiCollo));
882 }
883 }
884
885 return $newCollection;
886 }
887
888 /**
889 * @return void
890 */
891 private function addMissingReferenceId(): void
892 {
893 $this->transform(function (AbstractConsignment $consignment) {
894 if (null == $consignment->getReferenceId()) {
895 $consignment->setReferenceId('random_' . uniqid());
896 }
897
898 return $consignment;
899 });
900 }
901
902 /**
903 * @param mixed $id
904 *
905 * @return MyParcelCollection
906 */
907 private function findByReferenceIdGroup($id): MyParcelCollection
908 {
909 return $this->filter(function ($consignment) use ($id) {
910 /**
911 * @var AbstractConsignment $consignment
912 */
913 return Str::startsWith($consignment->getReferenceId(), $id);
914 });
915 }
916
917 /**
918 * Let the user of the SDK adjust the return consignment by means of a callback.
919 *
920 * @param array|AbstractConsignment[] $parentConsignments
921 * @param \Closure|null $modifier
922 *
923 * @return array|AbstractConsignment[]
924 */
925 private function getReturnConsignments(array $parentConsignments, ?\Closure $modifier): array
926 {
927 $returnConsignments = [];
928
929 foreach ($parentConsignments as $parentConsignment) {
930 $returnConsignment = clone $parentConsignment;
931 $returnConsignment->setDeliveryDate(null);
932 if ($modifier) {
933 $returnConsignment = $modifier($returnConsignment, $parentConsignment);
934 }
935 $returnConsignments[] = $returnConsignment;
936 }
937
938 return $returnConsignments;
939 }
940 }
941