diff --git a/Model/Resolver/PostnlTimeframes.php b/Model/Resolver/PostnlTimeframes.php new file mode 100644 index 00000000..5bd9e04c --- /dev/null +++ b/Model/Resolver/PostnlTimeframes.php @@ -0,0 +1,56 @@ +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; + } +} + diff --git a/Model/Resolver/SetPostnlShippingInformation.php b/Model/Resolver/SetPostnlShippingInformation.php new file mode 100644 index 00000000..0f213eaf --- /dev/null +++ b/Model/Resolver/SetPostnlShippingInformation.php @@ -0,0 +1,144 @@ +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; + } +} + diff --git a/etc/schema.graphqls b/etc/schema.graphqls new file mode 100644 index 00000000..d3a75d71 --- /dev/null +++ b/etc/schema.graphqls @@ -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.") +}