<?php
/*
* This file is part of the CouponPro42 Plugin
*
* Copyright (C) 2022 Diezon.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Plugin\CouponPro42\Service\PurchaseFlow\Processor;
use Eccube\Annotation\CartFlow;
use Eccube\Annotation\ShoppingFlow;
use Eccube\Annotation\OrderFlow;
use Eccube\Entity\BaseInfo;
use Eccube\Entity\ItemHolderInterface;
use Eccube\Entity\Master\OrderStatus;
use Eccube\Entity\Order;
use Eccube\Repository\BaseInfoRepository;
use Eccube\Service\PurchaseFlow\ItemHolderPreprocessor;
use Eccube\Service\PurchaseFlow\ProcessResult;
use Eccube\Service\PurchaseFlow\PurchaseContext;
use Eccube\Service\PurchaseFlow\PurchaseProcessor;
use Plugin\CouponPro42\Common\Constant;
use Plugin\CouponPro42\Entity\Coupon;
use Plugin\CouponPro42\Entity\Master\CouponKind;
use Plugin\CouponPro42\Entity\OrderCoupon;
use Plugin\CouponPro42\Repository\CouponRepository;
use Plugin\CouponPro42\Service\CouponHelper;
use Doctrine\ORM\EntityManagerInterface;
/**
* 購入フローにおけるクーポン処理.
* @ShoppingFlow
*/
class CouponItemProcessor implements ItemHolderPreprocessor
{
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @var CouponHelper
*/
protected $couponHelper;
/**
* @var BaseInfo
*/
protected $BaseInfo;
/**
* CouponItemProcessor constructor.
* @param EntityManagerInterface $entityManager
* @param CouponRepository $couponRepository
* @param CouponHelper $couponHelper
* @param BaseInfoRepository $baseInfoRepository
*/
public function __construct(EntityManagerInterface $entityManager,
CouponRepository $couponRepository,
CouponHelper $couponHelper,
BaseInfoRepository $baseInfoRepository)
{
$this->entityManager = $entityManager;
$this->couponRepository = $couponRepository;
$this->couponHelper = $couponHelper;
$this->BaseInfo = $baseInfoRepository->get();
}
/**
* {@inheritdoc}
*/
public function process(ItemHolderInterface $itemHolder, PurchaseContext $context)
{
if (!$itemHolder instanceof Order) {
return;
}
/** @var Order $Order */
$Order = $itemHolder;
/** @var Coupon $Coupon */
$Coupon = $this->couponRepository->findOneBy([
'coupon_code' => $Order->getCouponCode(),
'deleted' => false
]);
$this->couponHelper->removeCouponDiscountItem($Order);
if ($Coupon && $this->couponHelper->isCouponEnabled($Order, $Coupon)) {
// 購入フロー実行時、クーポン利用がある場合は割引明細を追加
$this->createOrderCoupon($Order, $Coupon);
$this->couponHelper->addCouponDiscountItem($Order, $Coupon);
// 購入フロー実行時、クーポン適用時、(商品代金-値引き額)に対して、送料無料(金額)を割った場合、送料を加算する.
$this->updateShippingFeeItem($Order);
}
}
/*
* Helper methods
*/
/**
* @param Order $Order
* @param Coupon $Coupon
*/
private function createOrderCoupon(Order $Order, Coupon $Coupon): void
{
$OrderCoupon = new OrderCoupon();
$OrderCoupon->setCoupon($Coupon)
->setOrder($Order)
->setCouponName($Coupon->getCouponName())
->setCouponKind($Coupon->getCouponKind())
->setCouponCode($Coupon->getCouponCode())
->setDiscountRate($Coupon->getDiscountRate());
$this->entityManager->persist($OrderCoupon);
$Order->setOrderCoupon($OrderCoupon);
}
/**
* (商品代金-値引き額)に対して、送料無料(金額)を割った場合、送料を加算する.
* @param Order $Order
*/
private function updateShippingFeeItem(Order $Order) {
if (!$this->BaseInfo->getDeliveryFreeAmount() || $Order->getSubtotal() < $this->BaseInfo->getDeliveryFreeAmount()) {
return;
}
// 複数配送を考慮しない
if ($Order->isMultiple()) {
return;
}
$total = 0;
$quantity = 0;
foreach ($Order->getProductOrderItems() as $OrderItem) {
$total += $OrderItem->getTotalPrice();
$quantity += $OrderItem->getQuantity();
}
// 送料無料(個数)を超えている場合は処理を行わない
if ($this->BaseInfo->getDeliveryFreeQuantity()) {
if ($quantity >= $this->BaseInfo->getDeliveryFreeQuantity()) {
return;
}
}
$totalAfterDiscount = $total;
foreach ($Order->getTaxFreeDiscountItems() as $OrderItem) {
if ($OrderItem->getProcessorName() == CouponItemProcessor::class) {
$totalAfterDiscount += $OrderItem->getTotalPrice();
}
}
$isDeliveryPaid = $totalAfterDiscount < $this->BaseInfo->getDeliveryFreeAmount();
if ($isDeliveryPaid) {
foreach ($Order->getItems() as $item) {
if ($item->isDeliveryFee()) {
$item->setQuantity(1);
}
}
}
}
}