Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions Model/Resolver/PostnlTimeframes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace TIG\PostNL\Model\Resolver;

use Magento\Checkout\Model\Session;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Model\MaskedQuoteIdToQuoteId;
use Magento\Quote\Model\Quote;
use TIG\PostNL\Service\Timeframe\Resolver;

class PostnlTimeframes implements ResolverInterface
{
public function __construct(
protected Session $checkoutSession,
protected MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId,
protected Resolver $timeframeResolver
) {
}

/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
/** @var \Magento\GraphQl\Model\Query\ContextInterface $context */
if (!isset($value['model']) && empty($args['cart_id'])) {
throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
}

$cartId = $args['cart_id'] ? $this->maskedQuoteIdToQuoteId->execute($args['cart_id']) : $value['model']->getId();
$this->checkoutSession->setQuoteId($cartId);
/** @var Quote $quote */
$quote = $this->checkoutSession->getQuote();

if (!isset($args['address'])) {
$args['address'] = $quote->getShippingAddress();
}

$timeframes = $this->timeframeResolver->processTimeframes($args['address']);

$timeframes['timeframes'] = array_merge(...$timeframes['timeframes']);

return $timeframes;
}
}

144 changes: 144 additions & 0 deletions Model/Resolver/SetPostnlShippingInformation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

declare(strict_types=1);

namespace TIG\PostNL\Model\Resolver;

use Magento\Checkout\Model\Session;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Model\MaskedQuoteIdToQuoteId;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteRepository;
use TIG\PostNL\Api\Data\OrderInterface;
use TIG\PostNL\Api\OrderRepositoryInterface;
use TIG\PostNL\Service\Action\OrderSave;
use TIG\PostNL\Service\Timeframe\Resolver;

class SetPostnlShippingInformation implements ResolverInterface
{
protected array $cache = [];

public function __construct(
protected Session $checkoutSession,
protected MaskedQuoteIdToQuoteId $maskedQuoteIdToQuoteId,
protected QuoteRepository $quoteRepository,
protected OrderSave $orderSave,
protected Resolver $timeframeResolver,
protected OrderRepositoryInterface $orderRepository
) {
}
/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
$cartId = $this->maskedQuoteIdToQuoteId->execute($args['input']['cart_id']);
/** @var Quote $quote */
$quote = $this->quoteRepository->get($cartId);
$this->checkoutSession->setQuote($quote);
$this->checkoutSession->replaceQuote($quote);

$shippingAddress = $quote->getShippingAddress();

$request = [
'type' => match ($args['input']['type']) {
'delivery' => 'delivery',
'pickup' => 'pickup',
default => throw new GraphQlInputException(__('Invalid delivery type provided.')),
},
'country' => $shippingAddress->getCountryId(),
'quote_id' => $quote->getId(),
'address' => [
'country' => $shippingAddress->getCountryId(),
'street' => $shippingAddress->getStreet(),
'postcode' => $shippingAddress->getPostcode(),
'housenumber' => $shippingAddress->getStreetLine(2),
],
'customerData' => [
'country' => $shippingAddress->getCountryId(),
'street' => $shippingAddress->getStreet(),
'postcode' => $shippingAddress->getPostcode(),
'housenumber' => $shippingAddress->getStreetLine(2),
'firstname' => $shippingAddress->getFirstname(),
'lastname' => $shippingAddress->getLastname(),
'telephone' => $shippingAddress->getTelephone()
],
'stated_address_only' => (bool)isset($args['input']['stated_address_only']) ? $args['input']['stated_address_only'] : false,
];

if ($request['type'] === 'pickup') {
$request = $this->processPickupRequest($request, $args['input']);
}
if ($request['type'] === 'delivery') {
$request = $this->processDeliveryRequest($request, $args['input']);
}

$this->orderSave->saveDeliveryOption(
$this->getPostnlOrder($quote),
$request
);

return ['model' => $quote];
}

protected function getPostnlOrder(Quote $quote): OrderInterface
{
$quoteId = $quote->getId();

if (!array_key_exists($quoteId, $this->cache)) {
$this->cache[$quoteId] = $this->orderRepository->getByQuoteId($quoteId);
if (!$this->cache[$quoteId]) {
$this->cache[$quoteId] = $this->orderRepository->create();
}
// Re-check that this order wasn't created an saved, in this case we need a new one.
if ($this->cache[$quoteId]->getOrderId()) {
$this->cache[$quoteId] = $this->orderRepository->create();
}
// Be sure to set quote id in the new model
$this->cache[$quoteId]->setQuoteId($quoteId);
}

return $this->cache[$quoteId];
}

public function processDeliveryRequest(array $request, array $input): array
{
$request['option'] = $input['option'] ?? null;
$request['date'] = $input['date'] ?? null;
$request['from'] = $input['from'] ?? null;
$request['to'] = $input['to'] ?? null;

return $request;
}

public function processPickupRequest(array $request, array $input): array
{
// TODO: Fully implement logic: https://github.com/postnl/postnl-magento2-hyva-checkout/blob/96dac6770ff055b24020db95c53fef2a788870d2/Magewire/SelectPickup.php#L194
$pickupLocation = $this->getPickupLocation($input['pickup_location_id']);
$request['option'] = $input['option'] ?? 'PG';
$request['from'] = $input['from'] ?? '15:00:00';
$request['date'] = $input['date'] ?? null;
$request['to'] = $input['to'] ?? null;
$request['LocationCode'] = $input['pickup_location_id'];
$request['name'] = $pickupLocation?->getName();
$request['RetailNetworkID'] = $pickupLocation?->getNetworkId();
$request['address'] = $pickupLocation?->getAddressArray();

return $request;
}

public function getPickupLocation(int $quoteId): ?\stdClass
{
// TODO: implement https://github.com/postnl/postnl-magento2-hyva-checkout/blob/96dac6770ff055b24020db95c53fef2a788870d2/Magewire/SelectPickup.php#L194
return null;
}
}

46 changes: 46 additions & 0 deletions etc/schema.graphqls
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

type Query {
postnlTimeframes (
cart_id: String! @doc(description: "Query by cart_id."),
address: PostNlAddressInput @doc(description: "Query by address."),
) : PostnlTimeframesOutput @resolver( class: "TIG\\PostNL\\Model\\Resolver\\PostnlTimeframes") @doc(description: "Query by Get the timeframes for the postnl shipping methods.")
}

type Mutation {
setPostnlShippingInformation (
input: PostnlShippingInformationInput! @doc(description: "Mutation to set the postnl shipping information.")
) : Cart @resolver( class: "TIG\\PostNL\\Model\\Resolver\\SetPostnlShippingInformation") @doc(description: "Query by Get the timeframes for the postnl shipping methods.")
}

input PostnlShippingInformationInput @doc(description: "Input for the postnl shipping information.") {
cart_id: String! @doc(description: "The cart ID for which the shipping information is being set.")
type: String! @doc(description: "The type of postnl delivery, either delivery or pickup.")
option: String!
date: String @doc(description: "The date of the delivery or pickup option.")
from: String @doc(description: "The start time of the delivery or pickup option.")
to: String @doc(description: "The end time of the delivery or pickup option.")
name: String @doc(description: "The name of the person receiving the delivery or pickup.")
pickup_location_id: String @doc(description: "The location code for the pickup point, if applicable.")
stated_address_only: Boolean @doc(description: "Should delivery only be done at the stated address.")
}

input PostNlAddressInput @doc(description: "address details needed for postnl") {
street: [String!]! @doc(description: "An array containing the street for the billing or shipping address.")
postcode: String! @doc(description: "The ZIP or postal code of the billing or shipping address.")
housenumber: String @doc(description: "The house number of the billing or shipping address.")
country: String! @doc(description: "The country code and label for the billing or shipping address.")
}

type PostnlTimeframesOutput {
timeframes: [PostnlTimeframes] @doc(description: "The result of the timeframes request.")
}

type PostnlTimeframes {
day: String @doc(description: "The day of the timeframe.")
from: String @doc(description: "The start time of the timeframe.")
from_friendly: String @doc(description: "The start time of the timeframe in a human-readable format.")
to: String @doc(description: "The end time of the timeframe.")
to_friendly: String @doc(description: "The end time of the timeframe in a human-readable format.")
option: String @doc(description: "The option of the timeframe.")
date: String @doc(description: "The date of the timeframe.")
}