Skip to content

Commit

Permalink
feat: add international mailbox for carriers with custom contract (#279)
Browse files Browse the repository at this point in the history
INT-353

---------

Co-authored-by: Edie Lemoine <[email protected]>
  • Loading branch information
FlorianSDV and EdieLemoine authored Jul 17, 2024
1 parent be42e93 commit 468ed0f
Show file tree
Hide file tree
Showing 128 changed files with 1,207 additions and 158 deletions.
4 changes: 3 additions & 1 deletion config/platform/flespakket.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use MyParcelNL\Pdk\Carrier\Model\Carrier;
use MyParcelNL\Pdk\Settings\Model\CheckoutSettings;
use MyParcelNL\Pdk\Shipment\Model\DeliveryOptions;
use MyParcelNL\Pdk\Validation\Validator\CarrierSchema;

return [
'name' => 'flespakket',
Expand Down Expand Up @@ -61,7 +62,8 @@
],
],
'features' => [
'labelDescriptionLength' => 45,
'labelDescriptionLength' => 45,
'carrierSmallPackageContract' => CarrierSchema::FEATURE_CUSTOM_CONTRACT_ONLY,
],
],
'returnCapabilities' => [
Expand Down
6 changes: 4 additions & 2 deletions config/platform/myparcel.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use MyParcelNL\Pdk\Carrier\Model\Carrier;
use MyParcelNL\Pdk\Settings\Model\CheckoutSettings;
use MyParcelNL\Pdk\Shipment\Model\DeliveryOptions;
use MyParcelNL\Pdk\Validation\Validator\CarrierSchema;

return [
'name' => 'myparcel',
Expand Down Expand Up @@ -62,8 +63,9 @@
],
],
'features' => [
'labelDescriptionLength' => 45,
'multiCollo' => true,
'labelDescriptionLength' => 45,
'carrierSmallPackageContract' => CarrierSchema::FEATURE_CUSTOM_CONTRACT_ONLY,
'multiCollo' => true,
],
],
'returnCapabilities' => [
Expand Down
15 changes: 9 additions & 6 deletions src/Account/Model/AccountGeneralSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@
* @property bool $isTest
* @property bool $orderMode
* @property bool $hasCarrierContract
* @property bool $hasCarrierSmallPackageContract
*/
class AccountGeneralSettings extends Model
{
public $attributes = [
'isTest' => false,
'orderMode' => false,
'hasCarrierContract' => false,
'isTest' => false,
'orderMode' => false,
'hasCarrierContract' => false,
'hasCarrierSmallPackageContract' => false,
];

public $casts = [
'isTest' => 'bool',
'orderMode' => 'bool',
'hasCarrierContract' => 'bool',
'isTest' => 'bool',
'orderMode' => 'bool',
'hasCarrierContract' => 'bool',
'hasCarrierSmallPackageContract' => 'bool',
];
}
1 change: 1 addition & 0 deletions src/Account/Model/Shop.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public function toStorableArray(): array
'label',
'primary',
'optional',
'type',
], Arrayable::STORABLE_NULL);
});

Expand Down
11 changes: 11 additions & 0 deletions src/Account/Service/AccountSettingsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ public function hasAccount(): bool
return null !== $this->getAccount();
}

/**
* @return bool
* @noinspection PhpUnused
*/
public function hasCarrierSmallPackageContract(): bool
{
$account = $this->getAccount();

return $account ? $account->generalSettings->hasCarrierSmallPackageContract : false;
}

/**
* @param string $feature
*
Expand Down
40 changes: 38 additions & 2 deletions src/App/Cart/Service/CartCalculationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,32 @@
use MyParcelNL\Pdk\App\Cart\Contract\CartCalculationServiceInterface;
use MyParcelNL\Pdk\App\Cart\Model\PdkCart;
use MyParcelNL\Pdk\App\ShippingMethod\Model\PdkShippingMethod;
use MyParcelNL\Pdk\Base\Contract\CountryServiceInterface;
use MyParcelNL\Pdk\Base\Service\WeightService;
use MyParcelNL\Pdk\Base\Support\Arr;
use MyParcelNL\Pdk\Facade\Pdk;
use MyParcelNL\Pdk\Facade\Settings;
use MyParcelNL\Pdk\Settings\Model\CarrierSettings;
use MyParcelNL\Pdk\Shipment\Collection\PackageTypeCollection;
use MyParcelNL\Pdk\Shipment\Model\DeliveryOptions;
use MyParcelNL\Pdk\Shipment\Model\PackageType;
use MyParcelNL\Pdk\Types\Service\TriStateService;

class CartCalculationService implements CartCalculationServiceInterface
{
/**
* @var \MyParcelNL\Pdk\Base\Contract\CountryServiceInterface
*/
private $countryService;

/**
* @param \MyParcelNL\Pdk\Base\Contract\CountryServiceInterface $countryService
*/
public function __construct(CountryServiceInterface $countryService)
{
$this->countryService = $countryService;
}

/**
* @param \MyParcelNL\Pdk\App\Cart\Model\PdkCart $cart
*
Expand All @@ -28,7 +44,6 @@ public function calculateAllowedPackageTypes(PdkCart $cart): PackageTypeCollecti
->sortBySize(true)
->filter(function (PackageType $packageType) use ($cart) {
$packageTypeName = $packageType->name;

if (DeliveryOptions::DEFAULT_PACKAGE_TYPE_NAME === $packageTypeName) {
return true;
}
Expand All @@ -37,7 +52,11 @@ public function calculateAllowedPackageTypes(PdkCart $cart): PackageTypeCollecti
&& $this->isWeightUnderPackageTypeLimit($cart, $packageType);

if (DeliveryOptions::PACKAGE_TYPE_MAILBOX_NAME === $packageTypeName) {
return $allowed && $this->calculateMailboxPercentage($cart) <= 100.0;
$cc = $cart->shippingMethod->shippingAddress->cc;

return $allowed
&& $this->allowMailboxToCountry($cc)
&& $this->calculateMailboxPercentage($cart) <= 100.0;
}

return $allowed;
Expand Down Expand Up @@ -98,6 +117,23 @@ protected function hasDeliveryOptions(PdkCart $cart): bool
return $anyItemIsDeliverable && ! $deliveryOptionsDisabled;
}

private function allowMailboxToCountry(?string $cc): bool
{
if ($cc === null) {
return false;
}

$countryIsUnique = $this->countryService->isUnique($cc);
$allowInternationalMailbox = Settings::all()->carrier->contains(function (CarrierSettings $carrierSettings) {
$allowInternationalMailbox = $carrierSettings->allowInternationalMailbox;
$hasDeliveryOptions = $carrierSettings->deliveryOptionsEnabled;

return $allowInternationalMailbox && $hasDeliveryOptions;
});

return $countryIsUnique || $allowInternationalMailbox;
}

/**
* @param \MyParcelNL\Pdk\App\Cart\Model\PdkCart $cart
* @param \MyParcelNL\Pdk\Shipment\Model\PackageType $packageType
Expand Down
39 changes: 33 additions & 6 deletions src/App/DeliveryOptions/Service/DeliveryOptionsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use MyParcelNL\Pdk\App\Cart\Model\PdkCart;
use MyParcelNL\Pdk\App\DeliveryOptions\Contract\DeliveryOptionsServiceInterface;
use MyParcelNL\Pdk\App\Tax\Contract\TaxServiceInterface;
use MyParcelNL\Pdk\Base\Contract\CountryServiceInterface;
use MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface;
use MyParcelNL\Pdk\Base\Contract\WeightServiceInterface;
use MyParcelNL\Pdk\Base\Support\Collection;
Expand Down Expand Up @@ -47,6 +48,11 @@ class DeliveryOptionsService implements DeliveryOptionsServiceInterface
'priceStandardDelivery' => CarrierSettings::PRICE_DELIVERY_TYPE_STANDARD,
];

/**
* @var \MyParcelNL\Pdk\Base\Contract\CountryServiceInterface
*/
private $countryService;

/**
* @var \MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface
*/
Expand All @@ -68,20 +74,24 @@ class DeliveryOptionsService implements DeliveryOptionsServiceInterface
private $taxService;

/**
* @param \MyParcelNL\Pdk\Base\Contract\CountryServiceInterface $countryService
* @param \MyParcelNL\Pdk\Base\Contract\CurrencyServiceInterface $currencyService
* @param \MyParcelNL\Pdk\Shipment\Contract\DropOffServiceInterface $dropOffService
* @param \MyParcelNL\Pdk\App\Tax\Contract\TaxServiceInterface $taxService
* @param \MyParcelNL\Pdk\Validation\Repository\SchemaRepository $schemaRepository
*/
public function __construct(
CountryServiceInterface $countryService,
CurrencyServiceInterface $currencyService,
DropOffServiceInterface $dropOffService,
TaxServiceInterface $taxService,
SchemaRepository $schemaRepository,
CurrencyServiceInterface $currencyService
SchemaRepository $schemaRepository
) {
$this->countryService = $countryService;
$this->currencyService = $currencyService;
$this->dropOffService = $dropOffService;
$this->taxService = $taxService;
$this->schemaRepository = $schemaRepository;
$this->currencyService = $currencyService;
}

/**
Expand Down Expand Up @@ -110,8 +120,7 @@ public function createAllCarrierSettings(PdkCart $cart): array

foreach ($carriers->all() as $carrier) {
$identifier = $carrier->externalIdentifier;
$settings['carrierSettings'][$identifier] =
$this->createCarrierSettings($carrier, $cart);
$settings['carrierSettings'][$identifier] = $this->createCarrierSettings($carrier, $cart, $packageType);
}

return $settings;
Expand All @@ -124,7 +133,7 @@ public function createAllCarrierSettings(PdkCart $cart): array
* @return array
* @throws \MyParcelNL\Pdk\Base\Exception\InvalidCastException
*/
private function createCarrierSettings(Carrier $carrier, PdkCart $cart): array
private function createCarrierSettings(Carrier $carrier, PdkCart $cart, string $packageType): array
{
$carrierSettings = new CarrierSettings(
Settings::get(sprintf('%s.%s', CarrierSettings::ID, $carrier->externalIdentifier))
Expand All @@ -140,6 +149,10 @@ private function createCarrierSettings(Carrier $carrier, PdkCart $cart): array
? $carrierSettings['dropOffDelay']
: $cart->shippingMethod->minimumDropOffDelay;

if ($this->shouldUseInternationalMailboxPrice($packageType, $cart->shippingMethod->shippingAddress->cc)) {
$carrierSettings->pricePackageTypeMailbox = $carrierSettings->priceInternationalMailbox;
}

$settings = $this->getBaseSettings($carrierSettings, $cart);

return array_merge(
Expand Down Expand Up @@ -238,4 +251,18 @@ function (Carrier $carrier) use ($cart, $weight, $packageType, $carrierSettings)

return [DeliveryOptions::DEFAULT_PACKAGE_TYPE_NAME, $allCarriers];
}

/**
* @param string $packageType
* @param null|string $cc
*
* @return bool
*/
private function shouldUseInternationalMailboxPrice(string $packageType, ?string $cc): bool
{
$isMailbox = $packageType === DeliveryOptions::PACKAGE_TYPE_MAILBOX_NAME;
$isNotUnique = $cc && ! $this->countryService->isUnique($cc);

return $isMailbox && $isNotUnique;
}
}
35 changes: 35 additions & 0 deletions src/App/Order/Calculator/General/PackageTypeCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
use MyParcelNL\Pdk\App\Order\Calculator\AbstractPdkOrderOptionCalculator;
use MyParcelNL\Pdk\App\Order\Model\PdkOrder;
use MyParcelNL\Pdk\Base\Contract\CountryServiceInterface;
use MyParcelNL\Pdk\Carrier\Model\Carrier;
use MyParcelNL\Pdk\Facade\AccountSettings;
use MyParcelNL\Pdk\Facade\Pdk;
use MyParcelNL\Pdk\Facade\Settings;
use MyParcelNL\Pdk\Shipment\Model\DeliveryOptions;
use MyParcelNL\Pdk\Validation\Validator\CarrierSchema;

final class PackageTypeCalculator extends AbstractPdkOrderOptionCalculator
{
Expand All @@ -29,18 +33,49 @@ public function __construct(PdkOrder $order)

public function calculate(): void
{
// All package types are allowed when shipping within the local country.
if ($this->countryService->isLocalCountry($this->order->shippingAddress->cc)) {
return;
}

// Letters are allowed outside the local country as well.
if (DeliveryOptions::PACKAGE_TYPE_LETTER_NAME === $this->order->deliveryOptions->packageType) {
return;
}

// Small packages are allowed outside the local country as well.
if (DeliveryOptions::PACKAGE_TYPE_PACKAGE_SMALL_NAME === $this->order->deliveryOptions->packageType) {
return;
}

$carrier = $this->order->deliveryOptions->carrier;

if ($this->isInternationalMailbox($carrier)) {
return;
}

$this->order->deliveryOptions->packageType = DeliveryOptions::PACKAGE_TYPE_PACKAGE_NAME;
}

/**
* @param \MyParcelNL\Pdk\Carrier\Model\Carrier $carrier
*
* @return bool
*/
private function isInternationalMailbox(Carrier $carrier): bool
{
$carrierSettings = Settings::all()->carrier->get($carrier->externalIdentifier);

/** @var \MyParcelNL\Pdk\Validation\Validator\CarrierSchema $schema */
$schema = Pdk::get(CarrierSchema::class);
$schema->setCarrier($carrier);

$isMailbox = $this->order->deliveryOptions->packageType === DeliveryOptions::PACKAGE_TYPE_MAILBOX_NAME;
$isNotUnique = ! $this->countryService->isUnique($this->order->shippingAddress->cc);
$enabledInAccount = AccountSettings::hasCarrierSmallPackageContract();
$canHaveCarrierSmallPackageContract = $schema->canHaveCarrierSmallPackageContract();
$enabledInSettings = $carrierSettings->allowInternationalMailbox;

return $isMailbox && $isNotUnique && $enabledInAccount && $canHaveCarrierSmallPackageContract && $enabledInSettings;
}
}
10 changes: 10 additions & 0 deletions src/Carrier/Model/Carrier.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* @property null|int $contractId
* @property bool $enabled
* @property bool $primary
* @property bool $isCustom
* @property bool $isDefault
* @property bool $optional
* @property null|string $label
Expand Down Expand Up @@ -154,6 +155,15 @@ public function getExternalIdentifierAttribute(): string
return $identifier ?: '?';
}

/**
* @return bool
* @noinspection PhpUnused
*/
public function getIsCustomAttribute(): bool
{
return ! $this->isDefault;
}

/**
* @return bool
* @noinspection PhpUnused
Expand Down
3 changes: 2 additions & 1 deletion src/Facade/AccountSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
* @method static CarrierCollection getCarriers()
* @method static null|Shop getShop()
* @method static bool hasCarrier(string $name)
* @method static bool hasTaxFields()
* @method static bool hasCarrierSmallPackageContract()
* @method static bool hasSubscriptionFeature(string $feature)
* @method static bool hasTaxFields()
* @method static bool usesOrderMode()
* @see \MyParcelNL\Pdk\Account\Contract\AccountSettingsServiceInterface
*/
Expand Down
Loading

0 comments on commit 468ed0f

Please sign in to comment.