PluginProbe
PostNL for WooCommerce / 4.0.1
PostNL for WooCommerce v4.0.1
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 / Model / Consignment / AbstractConsignment.php

AbstractConsignment.php in PostNL for WooCommerce 4.0.1, at includes/vendor/myparcelnl/sdk/src/Model/Consignment/AbstractConsignment.php

1,818 lines 39.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace MyParcelNL\Sdk\src\Model\Consignment;
6
7 use MyParcelNL\Sdk\src\Concerns\HasCheckoutFields;
8 use MyParcelNL\Sdk\src\Exception\MissingFieldException;
9 use MyParcelNL\Sdk\src\Helper\SplitStreet;
10 use MyParcelNL\Sdk\src\Helper\TrackTraceUrl;
11 use MyParcelNL\Sdk\src\Helper\ValidatePostalCode;
12 use MyParcelNL\Sdk\src\Model\MyParcelCustomsItem;
13 use MyParcelNL\Sdk\src\Support\Helpers;
14
15 /**
16 * A model of a consignment
17 * Class Consignment
18 */
19 class AbstractConsignment
20 {
21 use HasCheckoutFields;
22
23 /**
24 * Consignment types
25 */
26 public const DELIVERY_TYPE_MORNING = 1;
27 public const DELIVERY_TYPE_STANDARD = 2;
28 public const DELIVERY_TYPE_EVENING = 3;
29 public const DELIVERY_TYPE_PICKUP = 4;
30
31 /**
32 * @deprecated Since November 2019 is it no longer possible to use pickup express.
33 */
34 public const DELIVERY_TYPE_PICKUP_EXPRESS = 5;
35
36 public const DELIVERY_TYPE_MORNING_NAME = "morning";
37 public const DELIVERY_TYPE_STANDARD_NAME = "standard";
38 public const DELIVERY_TYPE_EVENING_NAME = "evening";
39 public const DELIVERY_TYPE_PICKUP_NAME = "pickup";
40
41 /**
42 * @deprecated Since November 2019 is it no longer possible to use pickup express.
43 */
44 public const DELIVERY_TYPE_PICKUP_EXPRESS_NAME = "pickup_express";
45
46 public const DELIVERY_TYPES_IDS = [
47 self::DELIVERY_TYPE_MORNING,
48 self::DELIVERY_TYPE_STANDARD,
49 self::DELIVERY_TYPE_EVENING,
50 self::DELIVERY_TYPE_PICKUP,
51 self::DELIVERY_TYPE_PICKUP_EXPRESS,
52 ];
53
54 public const DELIVERY_TYPES_NAMES = [
55 self::DELIVERY_TYPE_MORNING_NAME,
56 self::DELIVERY_TYPE_STANDARD_NAME,
57 self::DELIVERY_TYPE_EVENING_NAME,
58 self::DELIVERY_TYPE_PICKUP_NAME,
59 self::DELIVERY_TYPE_PICKUP_EXPRESS_NAME,
60 ];
61
62 public const DELIVERY_TYPES_NAMES_IDS_MAP = [
63 self::DELIVERY_TYPE_MORNING_NAME => self::DELIVERY_TYPE_MORNING,
64 self::DELIVERY_TYPE_STANDARD_NAME => self::DELIVERY_TYPE_STANDARD,
65 self::DELIVERY_TYPE_EVENING_NAME => self::DELIVERY_TYPE_EVENING,
66 self::DELIVERY_TYPE_PICKUP_NAME => self::DELIVERY_TYPE_PICKUP,
67 self::DELIVERY_TYPE_PICKUP_EXPRESS_NAME => self::DELIVERY_TYPE_PICKUP_EXPRESS,
68 ];
69
70 public const DEFAULT_DELIVERY_TYPE = self::DELIVERY_TYPE_STANDARD;
71 public const DEFAULT_DELIVERY_TYPE_NAME = self::DELIVERY_TYPE_STANDARD_NAME;
72
73 /**
74 * Customs declaration types
75 */
76 public const PACKAGE_CONTENTS_COMMERCIAL_GOODS = 1;
77 public const PACKAGE_CONTENTS_COMMERCIAL_SAMPLES = 2;
78 public const PACKAGE_CONTENTS_DOCUMENTS = 3;
79 public const PACKAGE_CONTENTS_GIFTS = 4;
80 public const PACKAGE_CONTENTS_RETRUN_SHIPMENT = 5;
81
82 /**
83 * Package types
84 */
85 public const PACKAGE_TYPE_PACKAGE = 1;
86 public const PACKAGE_TYPE_MAILBOX = 2;
87 public const PACKAGE_TYPE_LETTER = 3;
88 public const PACKAGE_TYPE_DIGITAL_STAMP = 4;
89
90 public const PACKAGE_TYPE_PACKAGE_NAME = "package";
91 public const PACKAGE_TYPE_MAILBOX_NAME = "mailbox";
92 public const PACKAGE_TYPE_LETTER_NAME = "letter";
93 public const PACKAGE_TYPE_DIGITAL_STAMP_NAME = "digital_stamp";
94
95 public const PACKAGE_TYPES_IDS = [
96 self::PACKAGE_TYPE_PACKAGE,
97 self::PACKAGE_TYPE_MAILBOX,
98 self::PACKAGE_TYPE_LETTER,
99 self::PACKAGE_TYPE_DIGITAL_STAMP,
100 ];
101
102 public const PACKAGE_TYPES_NAMES = [
103 self::PACKAGE_TYPE_PACKAGE_NAME,
104 self::PACKAGE_TYPE_MAILBOX_NAME,
105 self::PACKAGE_TYPE_LETTER_NAME,
106 self::PACKAGE_TYPE_DIGITAL_STAMP_NAME,
107 ];
108
109 public const PACKAGE_TYPES_NAMES_IDS_MAP = [
110 self::PACKAGE_TYPE_PACKAGE_NAME => self::PACKAGE_TYPE_PACKAGE,
111 self::PACKAGE_TYPE_MAILBOX_NAME => self::PACKAGE_TYPE_MAILBOX,
112 self::PACKAGE_TYPE_LETTER_NAME => self::PACKAGE_TYPE_LETTER,
113 self::PACKAGE_TYPE_DIGITAL_STAMP_NAME => self::PACKAGE_TYPE_DIGITAL_STAMP,
114 ];
115
116 public const DEFAULT_PACKAGE_TYPE = self::PACKAGE_TYPE_PACKAGE;
117 public const DEFAULT_PACKAGE_TYPE_NAME = self::PACKAGE_TYPE_PACKAGE_NAME;
118
119 /**
120 * Regular expression used to make sure the date is correct.
121 */
122 public const DATE_REGEX = '~(\d{4}-\d{2}-\d{2})$~';
123 public const DATE_TIME_REGEX = '~(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})$~';
124 public const STATUS_CONCEPT = 1;
125 public const MAX_STREET_LENGTH = 40;
126
127 public const CC_NL = 'NL';
128 public const CC_BE = 'BE';
129
130 /**
131 * @var array
132 */
133 public const INSURANCE_POSSIBILITIES_LOCAL = [];
134
135 /**
136 * @var string
137 */
138 protected $local_cc = '';
139
140 /**
141 * @internal
142 * @var string
143 */
144 public $reference_identifier;
145
146 /**
147 * @internal
148 * @var int
149 */
150 public $consignment_id;
151
152 /**
153 * @internal
154 * @var string|null
155 */
156 public $api_key;
157
158 /**
159 * @internal
160 * @var string|null
161 */
162 public $barcode;
163
164 /**
165 * @internal
166 * @var int
167 */
168 public $status = null;
169
170 /**
171 * @internal
172 * @var integer
173 */
174 public $shop_id;
175
176 /**
177 * @internal
178 * @var string
179 */
180 public $cc;
181
182 /**
183 * @internal
184 * @var string
185 */
186 public $city;
187
188 /**
189 * @internal
190 * @var string
191 */
192 public $street;
193
194 /**
195 * @internal
196 * @var string
197 */
198 public $street_additional_info;
199
200 /**
201 * @internal
202 * @var string|null
203 */
204 public $number;
205
206 /**
207 * @internal
208 * @var string
209 */
210 public $number_suffix = '';
211
212 /**
213 * @internal
214 * @var string
215 */
216 public $box_number = '';
217
218 /**
219 * @internal
220 * @var string
221 */
222 public $postal_code;
223
224 /**
225 * @internal
226 * @var string
227 */
228 public $person;
229
230 /**
231 * @internal
232 * @var string
233 */
234 public $company = '';
235
236 /**
237 * @internal
238 * @var string
239 */
240 public $email = '';
241
242 /**
243 * @internal
244 * @var string
245 */
246 public $phone = '';
247
248 /**
249 * @internal
250 * @var integer
251 */
252 public $package_type;
253
254 /**
255 * @internal
256 * @var integer
257 */
258 public $delivery_type = self::DEFAULT_DELIVERY_TYPE;
259
260 /**
261 * @internal
262 * @var string
263 */
264 public $delivery_date;
265
266 /**
267 * @internal
268 * @var boolean
269 */
270 public $only_recipient;
271
272 /**
273 * @internal
274 * @var boolean
275 */
276 public $signature;
277
278 /**
279 * @internal
280 * @var boolean
281 */
282 public $return;
283
284 /**
285 * @internal
286 * @var boolean
287 */
288 public $large_format;
289
290 /**
291 * @internal
292 * @var boolean
293 */
294 public $age_check;
295
296 /**
297 * @internal
298 * @var string
299 */
300 public $label_description = '';
301
302 /**
303 * @internal
304 * @var int
305 */
306 public $insurance = 0;
307
308 /**
309 * @internal
310 * @var array
311 */
312 public $physical_properties = [];
313
314 /**
315 * @internal
316 * @var int
317 */
318 public $contents = self::PACKAGE_CONTENTS_COMMERCIAL_GOODS;
319
320 /**
321 * @internal
322 * @var string
323 */
324 public $invoice;
325
326 /**
327 * @internal
328 * @var array
329 */
330 public $items = [];
331
332 /**
333 * @internal
334 * @var string
335 */
336 public $pickup_cc;
337
338 /**
339 * @internal
340 * @var string
341 */
342 public $pickup_postal_code;
343
344 /**
345 * @internal
346 * @var string
347 */
348 public $pickup_street;
349
350 /**
351 * @internal
352 * @var string
353 */
354 public $pickup_city;
355
356 /**
357 * @internal
358 * @var string
359 */
360 public $pickup_number;
361
362 /**
363 * @internal
364 * @var string
365 */
366 public $pickup_location_name;
367
368 /**
369 * @internal
370 * @var string
371 */
372 public $pickup_location_code = '';
373
374 /**
375 * @internal
376 * @var null|string
377 */
378 public $retail_network_id;
379
380 /**
381 * @var bool
382 */
383 private $partOfMultiCollo = false;
384
385 /**
386 * @var bool
387 */
388 private $auto_detect_pickup = true;
389
390 /**
391 * @var bool
392 */
393 private $save_recipient_address = true;
394
395 /**
396 * @var Helpers
397 */
398 private $helper;
399
400 public function __construct()
401 {
402 $this->helper = new Helpers();
403 }
404
405 /**
406 * @return array
407 */
408 public function getInsurancePossibilities(): array
409 {
410 return static::INSURANCE_POSSIBILITIES_LOCAL;
411 }
412
413 /**
414 * @return string|null
415 */
416 public function getReferenceId()
417 {
418 return $this->reference_identifier;
419 }
420
421 /**
422 * @param mixed $reference_identifier
423 *
424 * @return $this
425 */
426 public function setReferenceId(?string $reference_identifier): self
427 {
428 if ($reference_identifier !== null) {
429 $this->reference_identifier = (string) $reference_identifier;
430 }
431
432 return $this;
433 }
434
435 /**
436 * The id of the consignment
437 * Save this id in your database
438 *
439 * @return int|null
440 */
441 public function getConsignmentId(): ?int
442 {
443 return $this->consignment_id;
444 }
445
446 /**
447 * @param int|null $id
448 *
449 * @return $this
450 * @internal
451 * The id of the consignment
452 */
453 public function setConsignmentId(?int $id): self
454 {
455 $this->consignment_id = $id;
456
457 return $this;
458 }
459
460 /**
461 * @return string|null
462 */
463 public function getApiKey(): ?string
464 {
465 return $this->api_key;
466 }
467
468 /**
469 * Set the api key for each shipment.
470 * The key must be given to each shipment. So you can create multiple shipments
471 * in one time for different shops. This way you will not have to ask for the
472 * shop ID. The field shop ID is therefore not necessary.
473 * Required: Yes
474 *
475 * @param string $apiKey
476 *
477 * @return $this
478 */
479 public function setApiKey(string $apiKey): self
480 {
481 $this->api_key = $apiKey;
482
483 return $this;
484 }
485
486 /**
487 * @return int
488 */
489 public function getCarrierId(): int
490 {
491 /** @noinspection PhpUndefinedClassConstantInspection */
492 return static::CARRIER_ID;
493 }
494
495 /**
496 * @param bool $value
497 *
498 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
499 */
500 public function setMultiCollo(bool $value = true): self
501 {
502 $this->partOfMultiCollo = $value;
503
504 return $this;
505 }
506
507 /**
508 * @return bool
509 */
510 public function isPartOfMultiCollo(): bool
511 {
512 return $this->partOfMultiCollo;
513 }
514
515 /**
516 * @return string|null
517 */
518 public function getBarcode(): ?string
519 {
520 return $this->barcode;
521 }
522
523 /**
524 * @param string|null $barcode
525 *
526 * @return $this
527 * @internal
528 */
529 public function setBarcode(?string $barcode): self
530 {
531 $this->barcode = $barcode;
532
533 return $this;
534 }
535
536 /**
537 * Get the status of the consignment
538 * Pattern: [1 – 99]<br>
539 * Example:
540 * 1 pending - concept
541 * 2 pending - registered
542 * 3 enroute - handed to carrier
543 * 4 enroute - sorting
544 * 5 enroute - distribution
545 * 6 enroute - customs
546 * 7 delivered - at recipient
547 * 8 delivered - ready for pickup
548 * 9 delivered - package picked up
549 * 10 delivered - return shipment ready for pickup
550 * 11 delivered - return shipment package picked up
551 * 12 printed - letter
552 * 13 credit
553 * 30 inactive - concept
554 * 31 inactive - registered
555 * 32 inactive - enroute - handed to carrier
556 * 33 inactive - enroute - sorting
557 * 34 inactive - enroute - distribution
558 * 35 inactive - enroute - customs
559 * 36 inactive - delivered - at recipient
560 * 37 inactive - delivered - ready for pickup
561 * 38 inactive - delivered - package picked up
562 * 99 inactive - unknown
563 *
564 * @return int
565 */
566 public function getStatus(): int
567 {
568 return $this->status;
569 }
570
571 /**
572 * Status of the consignment
573 *
574 * @param int $status
575 *
576 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
577 * @internal
578 */
579 public function setStatus($status): self
580 {
581 $this->status = $status;
582
583 return $this;
584 }
585
586 /**
587 * @return integer|null
588 */
589 public function getShopId(): int
590 {
591 return $this->shop_id;
592 }
593
594 /**
595 * @param mixed $shop_id
596 *
597 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
598 * @internal
599 * The shop id to which this shipment belongs
600 * When the store ID is not specified, the API will look at the API key.
601 * Required: No
602 * @internal
603 */
604 public function setShopId($shop_id): self
605 {
606 $this->shop_id = $shop_id;
607
608 return $this;
609 }
610
611 /**
612 * @return string|null
613 */
614 public function getCountry()
615 {
616 return $this->cc;
617 }
618
619 /**
620 * The address country code
621 * ISO3166-1 alpha2 country code<br>
622 * <br>
623 * Pattern: [A-Z]{2}<br>
624 * Example: NL, BE, CW<br>
625 * Required: Yes
626 *
627 * @param string $cc
628 *
629 * @return $this
630 */
631 public function setCountry($cc)
632 {
633 $this->cc = $cc;
634
635 return $this;
636 }
637
638 /**
639 * Check if the address is outside the EU
640 *
641 * @return bool
642 * @todo move to hasCountry trait maken
643 */
644 public function isCdCountry()
645 {
646 return false === $this->isEuCountry();
647 }
648
649 /**
650 * Check if the address is inside the EU
651 *
652 * @return bool
653 * @todo move to hasCountry
654 */
655 public function isEuCountry()
656 {
657 return in_array(
658 $this->getCountry(),
659 [
660 'NL',
661 'BE',
662 'AT',
663 'BG',
664 'CZ',
665 'CY',
666 'DK',
667 'EE',
668 'FI',
669 'FR',
670 'DE',
671 'GR',
672 'HU',
673 'IE',
674 'IT',
675 'LV',
676 'LT',
677 'LU',
678 'PL',
679 'PT',
680 'RO',
681 'SK',
682 'SI',
683 'ES',
684 'SE',
685 'XK',
686 ]
687 );
688 }
689
690 /**
691 * @return string|null
692 */
693 public function getCity()
694 {
695 return $this->city;
696 }
697
698 /**
699 * The address city
700 * Required: Yes
701 *
702 * @param string $city
703 *
704 * @return $this
705 */
706 public function setCity($city)
707 {
708 $this->city = $city;
709
710 return $this;
711 }
712
713 /**
714 * @return string|null
715 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
716 * @var bool
717 */
718 public function getStreet($useStreetAdditionalInfo = false): string
719 {
720 if (null === $this->street) {
721 throw new MissingFieldException(
722 'First set the street with setStreet() before running getStreet()'
723 );
724 }
725
726 if ($useStreetAdditionalInfo && strlen($this->street) >= self::MAX_STREET_LENGTH) {
727 $streetParts = SplitStreet::getStreetParts($this->street);
728
729 return $streetParts[0];
730 }
731
732 return $this->street;
733 }
734
735 /**
736 * The address street name
737 * Required: Yes or use setFullStreet()
738 *
739 * @param string $street
740 *
741 * @return $this
742 */
743 public function setStreet($street)
744 {
745 $this->street = trim(str_replace('\n', ' ', $street));
746
747 return $this;
748 }
749
750 /**
751 * Get additional information for the street that should not be included in the street field
752 *
753 * @return string|null
754 * @todo move to hasStreet
755 */
756 public function getStreetAdditionalInfo(): ?string
757 {
758 if ($this->street === null) {
759 return null;
760 }
761
762 $streetParts = SplitStreet::getStreetParts($this->street);
763 $result = '';
764
765 if (isset($streetParts[1])) {
766 $result .= $streetParts[1];
767 }
768
769 $result .= ' ' . (string) $this->street_additional_info;
770
771 return trim($result);
772 }
773
774 /**
775 * The street additional info
776 * Required: No
777 *
778 * @param string $street_additional_info
779 *
780 * @return $this
781 */
782 public function setStreetAdditionalInfo(string $street_additional_info): self
783 {
784 $this->street_additional_info = $street_additional_info;
785
786 return $this;
787 }
788
789 /**
790 * Get entire street
791 *
792 * @return string Entire street
793 * @var bool
794 * @todo move to hasCountry
795 */
796 public function getFullStreet(bool $useStreetAdditionalInfo = false): string
797 {
798 $fullStreet = $this->getStreet($useStreetAdditionalInfo);
799
800 if ($this->getNumber()) {
801 $fullStreet .= ' ' . $this->getNumber();
802 }
803
804 if ($this->getBoxNumber()) {
805 $fullStreet .= ' ' . splitstreet::BOX_NL . ' ' . $this->getBoxNumber();
806 }
807
808 if ($this->getNumberSuffix()) {
809 $fullStreet .= ' ' . $this->getNumberSuffix();
810 }
811
812 return trim($fullStreet);
813 }
814
815 /**
816 * Splitting a full NL address and save it in this object
817 * Required: Yes or use setStreet()
818 *
819 * @param string $fullStreet
820 *
821 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
822 * @throws MissingFieldException
823 * @throws \BadMethodCallException
824 * @throws \Exception
825 */
826 public function setFullStreet(string $fullStreet): self
827 {
828 if ($this->getCountry() === null) {
829 throw new MissingFieldException(
830 'First set the country code with setCountry() before running setFullStreet()'
831 );
832 }
833
834 if (empty($this->local_cc)) {
835 throw new \BadMethodCallException('Can not create a shipment when the local country code is empty.');
836 }
837 $fullStreet = SplitStreet::splitStreet($fullStreet, $this->local_cc, $this->getCountry());
838 $this->setStreet($fullStreet->getStreet());
839 $this->setNumber($fullStreet->getNumber());
840 $this->setBoxNumber($fullStreet->getBoxNumber());
841 $this->setNumberSuffix($fullStreet->getNumberSuffix());
842
843 return $this;
844 }
845
846 /**
847 * @param bool $value
848 *
849 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
850 */
851 public function setSaveRecipientAddress(bool $value): self
852 {
853 $this->save_recipient_address = $value;
854
855 return $this;
856 }
857
858 /**
859 * @return bool
860 */
861 public function isSaveRecipientAddress(): bool
862 {
863 return $this->save_recipient_address;
864 }
865
866 /**
867 * @param string $barcode
868 * @param string $postalCode
869 * @param string $countryCode
870 *
871 * @return string
872 */
873 public function getBarcodeUrl(string $barcode, string $postalCode, string $countryCode): string
874 {
875 $barcodeUrl = TrackTraceUrl::create($barcode, $postalCode, $countryCode);
876
877 return $barcodeUrl;
878 }
879
880 /**
881 * @return string|null
882 */
883 public function getNumber(): ?string
884 {
885 return $this->number;
886 }
887
888 /**
889 * Street number
890 * Whole numeric value
891 * Pattern: [0-9]+
892 * Example: 10. 20. NOT 2,3
893 * Required: Yes for NL
894 *
895 * @param mixed $number
896 *
897 * @return $this
898 */
899 public function setNumber($number): self
900 {
901 $this->number = (string) $number;
902
903 return $this;
904 }
905
906 /**
907 * @return string|null
908 */
909 public function getNumberSuffix(): ?string
910 {
911 return $this->number_suffix;
912 }
913
914 /**
915 * Street number suffix.
916 * Required: no
917 *
918 * @param string|null $numberSuffix
919 *
920 * @return $this
921 */
922 public function setNumberSuffix(?string $numberSuffix): self
923 {
924 $this->number_suffix = $numberSuffix;
925
926 return $this;
927 }
928
929 /**
930 * @return string|null
931 */
932 public function getBoxNumber(): ?string
933 {
934 return $this->box_number;
935 }
936
937 /**
938 * Street number suffix.
939 * Required: no
940 *
941 * @param string|null $boxNumber
942 *
943 * @return $this
944 */
945 public function setBoxNumber(?string $boxNumber): self
946 {
947 $this->box_number = $boxNumber;
948
949 return $this;
950 }
951
952 /**
953 * @param array $consignmentEncoded
954 *
955 * @return array
956 */
957 public function encodeStreet(array $consignmentEncoded): array
958 {
959 $consignmentEncoded['recipient']['street'] = $this->getFullStreet(true);
960 $consignmentEncoded['recipient']['street_additional_info'] = $this->getStreetAdditionalInfo();
961
962 return $consignmentEncoded;
963 }
964
965 /**
966 * Check if address is correct
967 * Only for Dutch addresses
968 *
969 * @param $fullStreet
970 *
971 * @return bool
972 */
973 public function isCorrectAddress(string $fullStreet): bool
974 {
975 $localCountry = $this->local_cc;
976 $destinationCountry = $this->getCountry();
977
978 return SplitStreet::isCorrectStreet($fullStreet, $localCountry, $destinationCountry);
979 }
980
981 /**
982 * @return string|null
983 */
984 public function getPostalCode()
985 {
986 return $this->postal_code;
987 }
988
989 /**
990 * @param string $postalCode
991 *
992 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
993 * @throws \BadMethodCallException
994 * @throws \Exception
995 */
996 public function setPostalCode(string $postalCode): self
997 {
998 if ($this->getCountry() === null) {
999 throw new MissingFieldException(
1000 'First set the country code with setCountry() before running setPostalCode()'
1001 );
1002 }
1003 if (empty($this->local_cc)) {
1004 throw new \BadMethodCallException('Can not create a shipment when the local country code is empty.');
1005 }
1006
1007 if (! ValidatePostalCode::validate($postalCode, $this->getCountry())) {
1008 throw new \BadMethodCallException('Invalid postal code');
1009 }
1010
1011 $this->postal_code = $postalCode;
1012
1013 return $this;
1014 }
1015
1016 /**
1017 * @return string|null
1018 */
1019 public function getPerson(): string
1020 {
1021 return $this->person;
1022 }
1023
1024 /**
1025 * The person at this address
1026 * Required: Yes
1027 *
1028 * @param string $person
1029 *
1030 * @return $this
1031 */
1032 public function setPerson(string $person): self
1033 {
1034 $this->person = $person;
1035
1036 return $this;
1037 }
1038
1039 /**
1040 * @return string|null
1041 */
1042 public function getCompany(): ?string
1043 {
1044 return $this->company;
1045 }
1046
1047 /**
1048 * Company name
1049 * Required: no
1050 *
1051 * @param string|null $company
1052 *
1053 * @return $this
1054 */
1055 public function setCompany(?string $company): self
1056 {
1057 $this->company = $company;
1058
1059 return $this;
1060 }
1061
1062 /**
1063 * @return string
1064 */
1065 public function getEmail(): string
1066 {
1067 return $this->email;
1068 }
1069
1070 /**
1071 * The address email
1072 * Required: no
1073 *
1074 * @param string $email
1075 *
1076 * @return $this
1077 */
1078 public function setEmail(string $email): self
1079 {
1080 $this->email = $email;
1081
1082 return $this;
1083 }
1084
1085 /**
1086 * @return string|null
1087 */
1088 public function getPhone(): ?string
1089 {
1090 return $this->phone;
1091 }
1092
1093 /**
1094 * The address phone
1095 * Required: no
1096 *
1097 * @param string|null $phone
1098 *
1099 * @return $this
1100 */
1101 public function setPhone(?string $phone): ?self
1102 {
1103 $this->phone = $phone;
1104
1105 return $this;
1106 }
1107
1108 /**
1109 * @param int|null $default
1110 *
1111 * @return int|null
1112 */
1113 public function getPackageType($default = null): ?int
1114 {
1115 return $this->package_type ?? $default;
1116 }
1117
1118 /**
1119 * The package type
1120 * For international shipment only package type 1 is allowed
1121 * Pattern: [1 – 3]<br>
1122 * Example:
1123 * 1. package
1124 * 2. mailbox package
1125 * 3. letter
1126 * Required: Yes
1127 *
1128 * @param int $packageType
1129 *
1130 * @return $this
1131 */
1132 public function setPackageType(int $packageType): self
1133 {
1134 $this->package_type = $packageType;
1135
1136 return $this;
1137 }
1138
1139 /**
1140 * @return int
1141 */
1142 public function getDeliveryType(): int
1143 {
1144 return $this->delivery_type;
1145 }
1146
1147 /**
1148 * The delivery type for the package
1149 * Required: Yes if delivery_date has been specified
1150 *
1151 * @param int $deliveryType
1152 * @param bool $needDeliveryDate
1153 *
1154 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1155 */
1156 public function setDeliveryType(int $deliveryType, bool $needDeliveryDate = false): self
1157 {
1158 $this->delivery_type = $deliveryType;
1159
1160 return $this;
1161 }
1162
1163 /**
1164 * @param bool $value
1165 *
1166 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1167 */
1168 public function setAutoDetectPickup(bool $value): self
1169 {
1170 $this->auto_detect_pickup = $value;
1171
1172 return $this;
1173 }
1174
1175 /**
1176 * @return bool
1177 */
1178 public function isAutoDetectPickup(): bool
1179 {
1180 return $this->auto_detect_pickup;
1181 }
1182
1183 /**
1184 * @return string|null
1185 */
1186 public function getDeliveryDate(): ?string
1187 {
1188 return $this->delivery_date;
1189 }
1190
1191 /**
1192 * The delivery date time for this shipment
1193 * Pattern: YYYY-MM-DD | YYYY-MM-DD HH:MM:SS
1194 * Example: 2017-01-01 | 2017-01-01 00:00:00
1195 * Required: Yes if delivery type has been specified
1196 *
1197 * @param string|null $delivery_date
1198 *
1199 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1200 * @throws \BadMethodCallException
1201 */
1202 public function setDeliveryDate(?string $delivery_date): self
1203 {
1204 if (! $delivery_date) {
1205 $this->delivery_date = null;
1206
1207 return $this;
1208 }
1209
1210 $result = preg_match(self::DATE_REGEX, $delivery_date, $matches);
1211
1212 if ($result) {
1213 $delivery_date = (string) $delivery_date . ' 00:00:00';
1214 } else {
1215 $result = preg_match(self::DATE_TIME_REGEX, $delivery_date, $matches);
1216
1217 if (! $result) {
1218 throw new \BadMethodCallException(
1219 'Make sure the date ('
1220 . $delivery_date
1221 . ') is correct, like pattern: YYYY-MM-DD HH:MM:SS'
1222 . json_encode($matches)
1223 );
1224 }
1225 }
1226
1227 $this->delivery_date = (string) $delivery_date;
1228
1229 return $this;
1230 }
1231
1232 /**
1233 * @return bool
1234 */
1235 public function isOnlyRecipient(): bool
1236 {
1237 return false;
1238 }
1239
1240 /**
1241 * Deliver the package to the recipient only
1242 * Required: No
1243 *
1244 * @param bool $only_recipient
1245 *
1246 * @return $this
1247 */
1248 public function setOnlyRecipient(bool $only_recipient): self
1249 {
1250 if ($only_recipient) {
1251 throw new \BadMethodCallException('Only recipient has to be false in ' . static::class);
1252 }
1253
1254 return $this;
1255 }
1256
1257 /**
1258 * @return bool
1259 */
1260 public function isSignature(): bool
1261 {
1262 return false;
1263 }
1264
1265 /**
1266 * * Package must be signed for
1267 * Required: No
1268 *
1269 * @param bool $signature
1270 *
1271 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1272 */
1273 public function setSignature(bool $signature): self
1274 {
1275 if ($signature) {
1276 throw new \BadMethodCallException('Signature has to be false in ' . static::class);
1277 }
1278
1279 return $this;
1280 }
1281
1282 /**
1283 * Return the package if the recipient is not home
1284 *
1285 * @return boolean
1286 */
1287 public function isReturn()
1288 {
1289 return $this->return;
1290 }
1291
1292 /**
1293 * Return the package if the recipient is not home
1294 * Required: No
1295 *
1296 * @param bool $return
1297 *
1298 * @return $this
1299 * @throws \Exception
1300 */
1301 public function setReturn(bool $return): self
1302 {
1303 $this->return = $this->canHaveOption($return);
1304
1305 return $this;
1306 }
1307
1308 /**
1309 * @return bool
1310 */
1311 public function isLargeFormat(): bool
1312 {
1313 return false;
1314 }
1315
1316 /**
1317 * Large format package
1318 * Required: No
1319 *
1320 * @param bool $largeFormat
1321 *
1322 * @return $this
1323 */
1324 public function setLargeFormat(bool $largeFormat): self
1325 {
1326 if ($largeFormat) {
1327 throw new \BadMethodCallException('Large format has to be false in ' . static::class);
1328 }
1329
1330 return $this;
1331 }
1332
1333 /**
1334 * @return bool
1335 */
1336 public function hasAgeCheck(): bool
1337 {
1338 return false;
1339 }
1340
1341 /**
1342 * Age check
1343 * Required: No
1344 *
1345 * @param bool $ageCheck
1346 *
1347 * @return AbstractConsignment
1348 */
1349 public function setAgeCheck(bool $ageCheck): self
1350 {
1351 if ($ageCheck) {
1352 throw new \BadMethodCallException('Age check has to be false in ' . static::class);
1353 }
1354
1355 return $this;
1356 }
1357
1358 /**
1359 * @return string
1360 */
1361 public function getLabelDescription(): string
1362 {
1363 return $this->label_description;
1364 }
1365
1366 /**
1367 * This description will appear on the shipment label
1368 * Note: This will be overridden for return shipment by the following: Retour – 3SMYPAMYPAXXXXXX
1369 * Required: No
1370 *
1371 * @param mixed $label_description
1372 *
1373 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1374 */
1375 public function setLabelDescription($label_description): self
1376 {
1377 $this->label_description = (string) $label_description;
1378
1379 return $this;
1380 }
1381
1382 /**
1383 * @return int
1384 */
1385 public function getInsurance(): int
1386 {
1387 return $this->insurance;
1388 }
1389
1390 /**
1391 * Insurance price for the package.
1392 * Composite type containing integer and currency. The amount is without decimal separators.
1393 * Required: No
1394 *
1395 * @param int|null $insurance
1396 *
1397 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1398 * @throws \Exception
1399 */
1400 public function setInsurance(?int $insurance): self
1401 {
1402 if (null === $insurance) {
1403 $this->insurance = null;
1404
1405 return $this;
1406 }
1407
1408 if (empty(static::INSURANCE_POSSIBILITIES_LOCAL)) {
1409 throw new \BadMethodCallException('Property insurance_possibilities_local not found in ' . static::class);
1410 }
1411
1412 if (empty($this->local_cc)) {
1413 throw new \BadMethodCallException('Property local_cc not found in ' . static::class);
1414 }
1415
1416 if (! in_array($insurance, static::INSURANCE_POSSIBILITIES_LOCAL) && $this->getCountry() == $this->local_cc) {
1417 throw new \BadMethodCallException(
1418 'Insurance must be one of ' . implode(', ', static::INSURANCE_POSSIBILITIES_LOCAL)
1419 );
1420 }
1421
1422 if (! $this->canHaveOption()) {
1423 $insurance = 0;
1424 }
1425
1426 $this->insurance = $insurance;
1427
1428 return $this;
1429 }
1430
1431 /**
1432 * Required: Yes for non-EU shipments and digital stamps
1433 *
1434 * @param array $physical_properties
1435 *
1436 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1437 */
1438 public function setPhysicalProperties(array $physical_properties): self
1439 {
1440 $this->physical_properties = $physical_properties;
1441
1442 return $this;
1443 }
1444
1445 /**
1446 * @return array
1447 */
1448 public function getPhysicalProperties()
1449 {
1450 return $this->physical_properties;
1451 }
1452
1453 /**
1454 * @return integer
1455 */
1456 public function getContents(): int
1457 {
1458 return $this->contents;
1459 }
1460
1461 /**
1462 * The type of contents in the package.
1463 * The package contents are only needed in case of shipping outside EU,
1464 * this is mandatory info for customs form.
1465 * Pattern: [1 - 5]
1466 * Example: 1. commercial goods
1467 * 2. commercial samples
1468 * 3. documents
1469 * 4. gifts
1470 * 5. return shipment
1471 * Required: Yes for shipping outside EU
1472 *
1473 * @param int $contents
1474 *
1475 * @return $this
1476 */
1477 public function setContents(int $contents): self
1478 {
1479 $this->contents = $contents;
1480
1481 return $this;
1482 }
1483
1484 /**
1485 * @return string|null
1486 */
1487 public function getInvoice(): ?string
1488 {
1489 return $this->invoice;
1490 }
1491
1492 /**
1493 * The invoice number for the commercial goods or samples of package contents.
1494 * Required: Yes for international shipments
1495 *
1496 * @param string $invoice
1497 *
1498 * @return $this
1499 */
1500 public function setInvoice(string $invoice): self
1501 {
1502 $this->invoice = $invoice;
1503
1504 return $this;
1505 }
1506
1507 /**
1508 * @return MyParcelCustomsItem[]
1509 */
1510 public function getItems(): array
1511 {
1512 return $this->items;
1513 }
1514
1515 /**
1516 * A CustomsItem objects with description in the package.
1517 * Required: Yes for international shipments
1518 *
1519 * @param \MyParcelNL\Sdk\src\Model\MyParcelCustomsItem $item
1520 *
1521 * @return $this
1522 * @throws \MyParcelNL\Sdk\src\Exception\MissingFieldException
1523 */
1524 public function addItem(MyParcelCustomsItem $item): self
1525 {
1526 $item->ensureFilled();
1527
1528 $this->items[] = $item;
1529
1530 return $this;
1531 }
1532
1533 /**
1534 * @return string
1535 */
1536 public function getPickupCountry(): string
1537 {
1538 return $this->pickup_cc;
1539 }
1540
1541 /**
1542 * @param string $pickupCountry
1543 *
1544 * @return AbstractConsignment
1545 */
1546 public function setPickupCountry(string $pickupCountry): self
1547 {
1548 $this->pickup_cc = $pickupCountry;
1549
1550 return $this;
1551 }
1552
1553 /**
1554 * @return string|null
1555 */
1556 public function getPickupPostalCode(): ?string
1557 {
1558 return $this->pickup_postal_code;
1559 }
1560
1561 /**
1562 * Pattern: d{4}\s?[A-Z]{2}
1563 * Example: 2132BH
1564 * Required: Yes for pickup location
1565 *
1566 * @param string $pickup_postal_code
1567 *
1568 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1569 */
1570 public function setPickupPostalCode(string $pickup_postal_code): self
1571 {
1572 $this->pickup_postal_code = $pickup_postal_code;
1573
1574 return $this;
1575 }
1576
1577 /**
1578 * @return string|null
1579 */
1580 public function getPickupStreet(): string
1581 {
1582 return $this->pickup_street;
1583 }
1584
1585 /**
1586 * Pattern: [0-9A-Za-z]
1587 * Example: Burgemeester van Stamplein
1588 * Required: Yes for pickup location
1589 *
1590 * @param string $pickup_street
1591 *
1592 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1593 */
1594 public function setPickupStreet(string $pickup_street): self
1595 {
1596 $this->pickup_street = $pickup_street;
1597
1598 return $this;
1599 }
1600
1601 /**
1602 * @return string|null
1603 */
1604 public function getPickupCity(): string
1605 {
1606 return $this->pickup_city;
1607 }
1608
1609 /**
1610 * Pattern: [0-9A-Za-z]
1611 * Example: Hoofddorp
1612 * Required: Yes for pickup location
1613 *
1614 * @param string $pickup_city
1615 *
1616 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1617 */
1618 public function setPickupCity(string $pickup_city): self
1619 {
1620 $this->pickup_city = $pickup_city;
1621
1622 return $this;
1623 }
1624
1625 /**
1626 * @return string|null
1627 */
1628 public function getPickupNumber(): string
1629 {
1630 return $this->pickup_number;
1631 }
1632
1633 /**
1634 * Pattern: [0-9A-Za-z]
1635 * Example: 270
1636 * Required: Yes for pickup location
1637 *
1638 * @param string $pickup_number
1639 *
1640 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1641 */
1642 public function setPickupNumber(string $pickup_number): self
1643 {
1644 $this->pickup_number = (string) $pickup_number;
1645
1646 return $this;
1647 }
1648
1649 /**
1650 * @return string|null
1651 */
1652 public function getPickupLocationName(): ?string
1653 {
1654 return $this->pickup_location_name;
1655 }
1656
1657 /**
1658 * Pattern: [0-9A-Za-z]
1659 * Example: Albert Heijn
1660 * Required: Yes for pickup location
1661 *
1662 * @param string $pickup_location_name
1663 *
1664 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1665 */
1666 public function setPickupLocationName(string $pickup_location_name): self
1667 {
1668 $this->pickup_location_name = $pickup_location_name;
1669
1670 return $this;
1671 }
1672
1673 /**
1674 * @return string
1675 */
1676 public function getPickupLocationCode(): string
1677 {
1678 return $this->pickup_location_code;
1679 }
1680
1681 /**
1682 * Pattern: [0-9A-Za-z]
1683 * Example: Albert Heijn
1684 * Required: Yes for pickup location
1685 *
1686 * @param string $pickup_location_code
1687 *
1688 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1689 */
1690 public function setPickupLocationCode($pickup_location_code): self
1691 {
1692 $this->pickup_location_code = $pickup_location_code;
1693
1694 return $this;
1695 }
1696
1697 /**
1698 * @return null|string
1699 * @deprecated Use getRetailNetworkId instead
1700 *
1701 */
1702 public function getPickupNetworkId(): ?string
1703 {
1704 return $this->getRetailNetworkId();
1705 }
1706
1707 /**
1708 * @return null|string
1709 */
1710 public function getRetailNetworkId(): ?string
1711 {
1712 return $this->retail_network_id;
1713 }
1714
1715 /**
1716 * Pattern: [0-9A-Za-z]
1717 * Example: Albert Heijn
1718 * Required: Yes for pickup location
1719 *
1720 * @param string $retailNetworkId
1721 *
1722 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1723 * @deprecated Use setRetailNetworkId instead
1724 */
1725 public function setPickupNetworkId($retailNetworkId): self
1726 {
1727 if (! empty($retailNetworkId)) {
1728 throw new \BadMethodCallException('Pickup network id has to be empty in ' . static::class);
1729 }
1730
1731 return $this;
1732 }
1733
1734 /**
1735 * Pattern: [0-9A-Za-z]
1736 * Example: Albert Heijn
1737 * Required: Yes for pickup location
1738 *
1739 * @param string $retailNetworkId
1740 *
1741 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1742 */
1743 public function setRetailNetworkId(string $retailNetworkId): self
1744 {
1745 if (! empty($retailNetworkId)) {
1746 throw new \BadMethodCallException('Retail network id has to be empty in ' . static::class);
1747 }
1748
1749 return $this;
1750 }
1751
1752 /**
1753 * The total weight for all items in whole grams
1754 *
1755 * @return int
1756 */
1757 public function getTotalWeight(): int
1758 {
1759 if (! empty($this->getPhysicalProperties()['weight'])) {
1760 $weight = (int) $this->getPhysicalProperties()['weight'] ?? null;
1761 if ($weight) {
1762 return $weight;
1763 }
1764 }
1765
1766 $weight = 0;
1767
1768 foreach ($this->getItems() as $item) {
1769 $weight += $item->getWeight();
1770 }
1771
1772 if ($weight == 0) {
1773 $weight = 1;
1774 }
1775
1776 return $weight;
1777 }
1778
1779 /**
1780 * The weight has to be entered in grams
1781 *
1782 * @param int $weight
1783 *
1784 * @return \MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment
1785 */
1786 public function setTotalWeight(int $weight): self
1787 {
1788 $this->setPhysicalProperties(['weight' => $weight]);
1789
1790 return $this;
1791 }
1792
1793 /**
1794 * Only package type 1 can have extra options
1795 *
1796 * @param $option
1797 *
1798 * @return bool
1799 * @throws MissingFieldException
1800 */
1801 protected function canHaveOption(bool $option = true): bool
1802 {
1803 if ($this->getPackageType() === null) {
1804 throw new MissingFieldException('Set package type before ' . $option);
1805 }
1806
1807 return $this->getPackageType() == self::PACKAGE_TYPE_PACKAGE ? $option : false;
1808 }
1809
1810 /**
1811 * @return bool
1812 */
1813 public function validate(): bool
1814 {
1815 return true;
1816 }
1817 }
1818