Skip to content

Commit

Permalink
Compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
janbarasek committed Oct 24, 2021
1 parent f5aae66 commit 4838df6
Show file tree
Hide file tree
Showing 21 changed files with 615 additions and 56 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Shop Order
==========
Template
========

An e-shop order is an array of product items and quantities that are assigned to a variable symbol, customer and price.
This is a template package.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"baraja-core/shop-cart": "^1.0",
"baraja-core/shop-address": "^1.0",
"baraja-core/shop-customer": "^1.0",
"baraja-core/shop-currency": "^1.0",
"baraja-core/newsletter": "^1.0",
"baraja-core/emailer": "^1.0",
"baraja-core/variable-generator": "^2.0",
Expand Down
13 changes: 13 additions & 0 deletions src/Application/WebController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ public static function getLinkGenerator(): LinkGenerator
}


/**
* @return never-return
*/
public static function redirect(string $url): void
{
header('Location: ' . $url);
die;
}


/**
* @return never-return
*/
public function run(): void
{
$action = (string) preg_replace('~^order/?~', '', Url::get()->getRelativeUrl(false));
Expand Down
178 changes: 178 additions & 0 deletions src/Bridge/BalikoBotAdapterBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

declare(strict_types=1);

namespace Baraja\Shop\Order\Bridge;


use Baraja\PhoneNumber\PhoneNumberFormatter;
use Baraja\Shop\Delivery\Entity\Delivery;
use Baraja\Shop\Order\Delivery\Carrier\CarrierAdapter;
use Baraja\Shop\Order\Entity\Order;
use Baraja\Shop\Order\Entity\OrderPackage;
use Doctrine\ORM\EntityManagerInterface;
use Inspirum\Balikobot\Model\Aggregates\PackageCollection;
use Inspirum\Balikobot\Model\Values\Package;
use Inspirum\Balikobot\Services\Balikobot;
use Inspirum\Balikobot\Services\Requester;

final class BalikoBotAdapterBridge implements CarrierAdapter
{
private ?Balikobot $bot = null;


public function __construct(
private string $apiUser,
private string $apiKey,
private EntityManagerInterface $entityManager
) {
}


/**
* @return array<int, string>
*/
public function getCompatibleCarriers(): array
{
return ['zasilkovna', 'gls'];
}


/**
* @param array<int, Order> $orders
*/
public function createPackages(array $orders): void
{
if (count($orders) === 0) {
return;
}
$primaryShipper = null;
foreach ($orders as $order) {
$delivery = $order->getDelivery();
if ($delivery === null) {
continue;
}
$shipperTemp = $delivery->getBotShipper();
if ($shipperTemp === null) {
throw new \InvalidArgumentException('Shipper type can not be empty.');
}
if ($primaryShipper === null) {
$primaryShipper = $shipperTemp;
} elseif ($primaryShipper !== $shipperTemp) {
throw new \InvalidArgumentException(
'These orders cannot be sent at the same time. Always select only one carrier.',
);
}
}

// create new package collection for specific shipper
assert($primaryShipper !== null);
$packages = new PackageCollection($primaryShipper);

// add package to collection
foreach ($orders as $order) {
$delivery = $order->getDelivery();
if ($delivery === null || $delivery->getBotShipper() === null) {
continue;
}
try {
$packages->add($this->createPackageEntity($order, $delivery));
} catch (\Throwable $e) {
throw new \InvalidArgumentException(
'Invalid order "' . $order->getNumber() . '": ' . $e->getMessage(),
$e->getCode(),
$e,
);
}
}

$bot = $this->getBotService();
// upload packages to balikobot
$responsePackages = $bot->addPackages($packages);

// order shipment for packages
$orderedShipment = $bot->orderShipment($responsePackages);

// save track URL for each package
foreach ($responsePackages as $key => $orderedPackage) {
$order = $orders[$key] ?? null;
$packageRecord = new OrderPackage(
order: $order,
orderId: $orderedShipment->getOrderId(),
packageId: $orderedPackage->getPackageId(),
batchId: $orderedPackage->getBatchId(),
shipper: $orderedPackage->getShipper(),
carrierId: $orderedPackage->getCarrierId(),
);
$packageRecord->setTrackUrl($orderedPackage->getTrackUrl());
$packageRecord->setLabelUrl($orderedPackage->getLabelUrl());
$packageRecord->setCarrierIdSwap($orderedPackage->getCarrierIdSwap());
$packageRecord->setPieces($orderedPackage->getPieces());
$packageRecord->setFinalCarrierId($orderedPackage->getFinalCarrierId());
$packageRecord->setFinalTrackUrl($orderedPackage->getFinalTrackUrl());
$this->entityManager->persist($packageRecord);
$this->entityManager->getUnitOfWork()->commit($packageRecord);
}

$handoverUrl = $orderedShipment->getHandoverUrl();
foreach ($orders as $order) {
if ($order !== null) {
$order->setHandoverUrl($handoverUrl);
}
}
$this->entityManager->flush();
}


private function createPackageEntity(Order $order, Delivery $delivery): Package
{
$serviceType = $delivery->getBotServiceType();
if ($serviceType === null) {
throw new \InvalidArgumentException(
'Service type can not be undefined (delivery ID: ' . $delivery->getId() . ').',
);
}

$package = new Package;
$package->setServiceType($serviceType);
$package->setRecEmail($order->getCustomer()->getEmail());
$package->setRecName($order->getDeliveryAddress()->getPersonName());
$package->setRecStreet($order->getDeliveryAddress()->getStreet());
$package->setRecCity($order->getDeliveryAddress()->getCity());
$package->setRecZip($order->getDeliveryAddress()->getZip());
$package->setRecCountry($order->getDeliveryAddress()->getCountry()->getCode());
$phone = $this->formatPhone((string) $order->getCustomer()->getPhone());
if ($phone !== null) {
$package->setRecPhone($phone);
}
$package->setPrice($order->getPrice());
$package->setInsCurrency('CZK'); // TODO: hardcoded
$package->setWeight(0.4); // TODO: hardcoded
if ($order->getDeliveryBranchId()) {
$package->setBranchId((string) $order->getDeliveryBranchId());
}

return $package;
}


private function getBotService(): Balikobot
{
if ($this->bot === null) {
$this->bot = new Balikobot(new Requester($this->apiUser, $this->apiKey));
}

return $this->bot;
}


private function formatPhone(string $phone): ?string
{
if (trim($phone) === '') {
return null;
}
$phone = (string) preg_replace('/^\+\d{1,3}\s+/', '', PhoneNumberFormatter::fix($phone));

return (string) preg_replace('/\D+/', '', $phone);
}
}
16 changes: 10 additions & 6 deletions src/Bridge/CustomerOrderBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@
namespace Baraja\Shop\Order;


use Baraja\Doctrine\EntityManager;
use Baraja\Shop\Customer\OrderLoader;
use Baraja\Shop\Order\Entity\Order;
use Nette\Utils\DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;

final class CustomerOrderBridge implements OrderLoader
{
public function __construct(
private EntityManager $entityManager,
private EntityManagerInterface $entityManager,
) {
}


/**
* @return array<int, array{id: int, number: string, price: float, date: \DateTime}>
* @return array<int, array{id: int, number: string, price: float, date: \DateTimeImmutable}>
*/
public function getOrders(int $customerId): array
{
/** @var Order[] $orders */
$orders = $this->entityManager->getRepository(Order::class)
$orders = (new EntityRepository(
$this->entityManager,
$this->entityManager->getClassMetadata(Order::class)
))
->createQueryBuilder('o')
->where('o.customer = :customerId')
->setParameter('customerId', $customerId)
Expand All @@ -33,11 +36,12 @@ public function getOrders(int $customerId): array

$return = [];
foreach ($orders as $order) {
$date = $order->getInsertedDate();
$return[] = [
'id' => (int) $order->getId(),
'number' => $order->getNumber(),
'price' => $order->getPrice(),
'date' => DateTime::from($order->getInsertedDate()),
'date' => new \DateTimeImmutable($date->format('Y-m-d H:i:s.u'), $date->getTimezone()),
];
}

Expand Down
19 changes: 12 additions & 7 deletions src/Bridge/GoPayGatewayBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,32 @@

use Baraja\Doctrine\EntityManager;
use Baraja\DynamicConfiguration\Configuration;
use Baraja\Shop\Currency\CurrencyManager;
use Baraja\Shop\Order\Application\WebController;
use Baraja\Shop\Order\Entity\Order;
use Baraja\Shop\Order\Entity\OrderOnlinePayment;
use Baraja\Shop\Order\Entity\OrderStatus;
use Baraja\Shop\Order\Payment\Gateway\Gateway;
use Baraja\Shop\Order\Payment\Gateway\GatewayResponse;
use Baraja\Shop\Order\Payment\OrderPaymentProvider;
use Contributte\GopayInline\Api\Entity\PaymentFactory;
use Contributte\GopayInline\Api\Lists\Currency;
use Contributte\GopayInline\Api\Lists\PaymentInstrument;
use Contributte\GopayInline\Api\Lists\PaymentState;
use Contributte\GopayInline\Client;
use Contributte\GopayInline\Config;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Psr\Log\LoggerInterface;
use Tracy\Debugger;
use Tracy\Dumper;
use Tracy\ILogger;

final class GoPayGatewayBridge implements Gateway, OrderPaymentProvider
final class GoPayGatewayBridge implements Gateway
{
public function __construct(
private OrderStatusManager $orderStatusManager,
private EntityManager $entityManager,
private Configuration $configuration,
private Emailer $emailer,
private CurrencyManager $currencyManager,
private ?LoggerInterface $logger = null,
) {
}

Expand All @@ -52,7 +52,7 @@ public function pay(Order $order): GatewayResponse
],
],
'amount' => $order->getPrice(),
'currency' => Currency::CZK, // TODO: Use default currency
'currency' => $this->currencyManager->getMainCurrency()->getCode(),
'order_number' => $order->getNumber(),
'order_description' => 'Objednávka ' . $order->getNumber(),
'items' => [
Expand Down Expand Up @@ -87,7 +87,12 @@ public function pay(Order $order): GatewayResponse
return new GatewayResponse($response['gw_url']);
}

Debugger::log(new \Exception(Dumper::toText($response)), ILogger::CRITICAL);
if ($this->logger !== null) {
$this->logger->critical(
'Gateway error: ' . json_encode($response, JSON_THROW_ON_ERROR),
iterator_to_array($response->getIterator()),
);
}

return new GatewayResponse(
WebController::getLinkGenerator()->default($order),
Expand Down
Loading

0 comments on commit 4838df6

Please sign in to comment.