Skip to content

Commit a589056

Browse files
fix(php-sdk): correctly pass attributes for each multi-collo shipment (#533)
* fix(php-sdk): correctly pass attributes for each multi-collo shipment * fix: implement feedback * fix: implement feedback * fix: Support unique consignment options in multi collo shipments * fix: Only set multi collo if reference_identifiers match * fix: Implement feedback Joeri * fix: Implement feedback
1 parent 5330de6 commit a589056

File tree

2 files changed

+196
-25
lines changed

2 files changed

+196
-25
lines changed

src/Helper/MyParcelCollection.php

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,72 @@ public function addConsignment(AbstractConsignment $consignment): self
172172
if ($consignment->getApiKey() === null) {
173173
throw new MissingFieldException('First set the API key with setApiKey() before running addConsignment()');
174174
}
175-
176175
$consignment->validate();
177-
178176
$this->push($consignment);
179177

180178
return $this;
181179
}
182180

181+
/**
182+
* @param AbstractConsignment $consignment
183+
* @param int $amount
184+
*
185+
* @return self
186+
* @throws MissingFieldException
187+
*/
188+
public function addMultiCollo(AbstractConsignment $consignment, int $amount): self
189+
{
190+
if ($amount <= 1) {
191+
$this->addConsignment($consignment);
192+
return $this;
193+
}
194+
195+
// Create multiple consignments with equally distributed weight
196+
$originalWeight = $consignment->getTotalWeight();
197+
$weightPerCollo = $originalWeight / $amount;
198+
199+
$consignments = [];
200+
for ($i = 1; $i <= $amount; $i++) {
201+
$clonedConsignment = clone $consignment;
202+
$clonedConsignment->setTotalWeight($weightPerCollo);
203+
$consignments[] = $clonedConsignment;
204+
}
205+
206+
return $this->addMultiColloConsignments($consignments);
207+
}
208+
209+
/**
210+
* @param AbstractConsignment[] $consignments
211+
*
212+
* @return self
213+
* @throws MissingFieldException
214+
* @throws \Exception
215+
*/
216+
public function addMultiColloConsignments(array $consignments): self
217+
{
218+
if (empty($consignments)) {
219+
return $this;
220+
}
221+
222+
// Check if all consignments have the same carrier
223+
$carrierIds = array_map(static function($consignment) {
224+
return $consignment->getCarrierId();
225+
}, $consignments);
226+
if (count(array_unique($carrierIds)) > 1) {
227+
throw new \Exception('All consignments in a multi collo shipment must have the same carrier.');
228+
}
229+
230+
// Set multi collo and reference identifier for all consignments
231+
$referenceId = $consignments[0]->getReferenceIdentifier() ?? ('multi_collo_' . uniqid('', true));
232+
foreach ($consignments as $consignment) {
233+
$consignment->setMultiCollo(true);
234+
$consignment->setReferenceIdentifier($referenceId);
235+
$this->addConsignment($consignment);
236+
}
237+
238+
return $this;
239+
}
240+
183241
/**
184242
* @param int[] $ids
185243
* @param string $apiKey
@@ -220,29 +278,6 @@ public function addConsignmentByReferenceIds($ids, $apiKey): self
220278
return $this;
221279
}
222280

223-
/**
224-
* @param AbstractConsignment $consignment
225-
* @param $amount
226-
*
227-
* @return self
228-
*/
229-
public function addMultiCollo(AbstractConsignment $consignment, $amount): self
230-
{
231-
if ($amount > 1) {
232-
$consignment->setMultiCollo();
233-
}
234-
235-
if ($consignment->isPartOfMultiCollo() && ! $consignment->getReferenceIdentifier()) {
236-
$consignment->setReferenceIdentifier('random_multi_collo_' . uniqid('', true));
237-
}
238-
239-
for ($i = 1; $i <= $amount; $i++) {
240-
$this->push($consignment);
241-
}
242-
243-
return $this;
244-
}
245-
246281
/**
247282
* Create concepts in MyParcel.
248283
*
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MyParcelNL\Sdk\Test\Model\Consignment;
6+
7+
use MyParcelNL\Sdk\Model\Carrier\CarrierPostNL;
8+
use MyParcelNL\Sdk\Model\Carrier\CarrierDPD;
9+
use MyParcelNL\Sdk\Model\Consignment\AbstractConsignment;
10+
use MyParcelNL\Sdk\Model\Consignment\PostNLConsignment;
11+
use MyParcelNL\Sdk\Model\Consignment\DPDConsignment;
12+
use MyParcelNL\Sdk\Test\Bootstrap\ConsignmentTestCase;
13+
use MyParcelNL\Sdk\Helper\MyParcelCollection;
14+
15+
class MultiColloConsignmentTest extends ConsignmentTestCase
16+
{
17+
public function provideMultiColloData(): array
18+
{
19+
return [
20+
'two parcels with different weight and options' => [
21+
[
22+
(new PostNLConsignment())
23+
->setApiKey('irrelevant')
24+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
25+
->setTotalWeight(1000)
26+
->setSignature(true),
27+
(new PostNLConsignment())
28+
->setApiKey('irrelevant')
29+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
30+
->setTotalWeight(2000)
31+
->setAgeCheck(true),
32+
],
33+
true, // should support multi collo
34+
],
35+
'one parcel' => [
36+
[
37+
(new PostNLConsignment())
38+
->setApiKey('irrelevant')
39+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
40+
->setTotalWeight(1500),
41+
],
42+
true,
43+
],
44+
'three parcels' => [
45+
[
46+
(new PostNLConsignment())
47+
->setApiKey('irrelevant')
48+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
49+
->setTotalWeight(500),
50+
(new PostNLConsignment())
51+
->setApiKey('irrelevant')
52+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
53+
->setTotalWeight(750),
54+
(new PostNLConsignment())
55+
->setApiKey('irrelevant')
56+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
57+
->setTotalWeight(1250),
58+
],
59+
true,
60+
],
61+
'different carriers (should fail)' => [
62+
[
63+
(new PostNLConsignment())
64+
->setApiKey('irrelevant')
65+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
66+
->setTotalWeight(1000),
67+
(new DPDConsignment())
68+
->setApiKey('irrelevant')
69+
->setPackageType(AbstractConsignment::PACKAGE_TYPE_PACKAGE)
70+
->setTotalWeight(2000),
71+
],
72+
false,
73+
],
74+
];
75+
}
76+
77+
/**
78+
* @dataProvider provideMultiColloData
79+
*/
80+
public function testMultiColloConsignments(array $consignments, bool $shouldSupportMultiCollo): void
81+
{
82+
$collection = new MyParcelCollection();
83+
$exceptionThrown = false;
84+
try {
85+
$collection->addMultiColloConsignments($consignments);
86+
} catch (\Exception $e) {
87+
$exceptionThrown = true;
88+
}
89+
90+
if (! $shouldSupportMultiCollo) {
91+
self::assertTrue($exceptionThrown, 'Expected exception for different carriers.');
92+
return;
93+
}
94+
95+
self::assertCount(count($consignments), $collection, 'Number of consignments in collection does not match.');
96+
97+
// Check multi collo properties if more than one consignment
98+
if (count($consignments) > 1) {
99+
$referenceId = $collection->getConsignments()[0]->getReferenceIdentifier();
100+
foreach ($collection as $index => $consignment) {
101+
self::assertTrue(
102+
$consignment->isPartOfMultiCollo(),
103+
sprintf('Consignment %d is not marked as multi collo.', $index + 1)
104+
);
105+
self::assertEquals(
106+
$referenceId,
107+
$consignment->getReferenceIdentifier(),
108+
sprintf('Consignment %d does not have the correct reference identifier.', $index + 1)
109+
);
110+
}
111+
}
112+
113+
// Check that shipment options and weight are unique per consignment
114+
foreach ($collection as $index => $consignment) {
115+
self::assertEquals(
116+
$consignments[$index]->getTotalWeight(),
117+
$consignment->getTotalWeight(),
118+
sprintf('Consignment %d does not have the correct weight.', $index + 1)
119+
);
120+
if (method_exists($consignments[$index], 'isSignature')) {
121+
self::assertEquals(
122+
$consignments[$index]->isSignature(),
123+
$consignment->isSignature(),
124+
sprintf('Consignment %d does not have the correct signature option.', $index + 1)
125+
);
126+
}
127+
if (method_exists($consignments[$index], 'hasAgeCheck')) {
128+
self::assertEquals(
129+
$consignments[$index]->hasAgeCheck(),
130+
$consignment->hasAgeCheck(),
131+
sprintf('Consignment %d does not have the correct age check option.', $index + 1)
132+
);
133+
}
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)