Skip to content

Commit

Permalink
[shopsys] promo code for free transport and payment (#3625)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitek-rostislav authored Dec 17, 2024
2 parents 933dc25 + 266a12d commit 43cf620
Show file tree
Hide file tree
Showing 52 changed files with 660 additions and 402 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PromoCodeTypeEnum:
type: enum
inherits:
- 'PromoCodeTypeEnumDecorator'
4 changes: 4 additions & 0 deletions app/config/graphql/types/ModelType/Cart/PromoCode.types.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PromoCode:
type: object
inherits:
- 'PromoCodeDecorator'
2 changes: 2 additions & 0 deletions app/config/packages/shopsys_framework.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ shopsys_framework:
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\AddProductsMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\ApplyPercentagePromoCodeMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\ApplyNominalPromoCodeMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\ApplyFreeTransportAndPaymentPromoCodeMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\FreeTransportAndPaymentInformationMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\AddTransportMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\AddPaymentMiddleware'
- 'Shopsys\FrameworkBundle\Model\Order\Processing\OrderProcessorMiddleware\PersonalPickupPointMiddleware'
Expand Down
19 changes: 18 additions & 1 deletion app/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ type Cart {
"Selected bank swift code of goPay payment bank transfer"
paymentGoPayBankSwift: String
"Applied promo code if provided"
promoCode: String
promoCode: PromoCode
"Remaining amount for free transport and payment; null = transport cannot be free"
remainingAmountWithVatForFreeTransport: Money
"Rounding amount if payment has rounding allowed"
Expand Down Expand Up @@ -1923,6 +1923,23 @@ enum ProductTypeEnum {
INQUIRY
}

type PromoCode {
"Code of the promo code"
code: String!
"Type of the promo code"
type: PromoCodeTypeEnum!
}

"One of possible promo code types"
enum PromoCodeTypeEnum {
"Discount type free transport and payment"
free_transport_payment
"Discount type nominal"
nominal
"Discount type percent"
percent
}

type Query {
"Access personal data using hash received in email from personal data access request"
accessPersonalData(
Expand Down
23 changes: 21 additions & 2 deletions app/src/DataFixtures/Demo/PromoCodeDataFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeFlag\PromoCodeFlagFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeLimit\PromoCodeLimitFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeProduct\PromoCodeProductFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeTypeEnum;
use Shopsys\FrameworkBundle\Model\Pricing\Group\PricingGroup;

class PromoCodeDataFixture extends AbstractReferenceFixture implements DependentFixtureInterface
Expand All @@ -28,6 +29,7 @@ class PromoCodeDataFixture extends AbstractReferenceFixture implements Dependent
public const string PROMO_CODE_FOR_REGISTERED_ONLY = 'promo_code_for_registered_only';
public const string PROMO_CODE_FOR_VIP_PRICING_GROUP = 'promo_code_for_vip_pricing_group';
public const string PROMO_CODE_FOR_NEW_PRODUCT = 'promo_code_for_new_product';
public const string PROMO_CODE_FOR_FREE_TRANSPORT_PAYMENT = 'promo_code_for_free_transport_and_payemnt';

/**
* @param \App\Model\Order\PromoCode\PromoCodeFacade $promoCodeFacade
Expand Down Expand Up @@ -131,11 +133,13 @@ public function load(ObjectManager $manager): void

$promoCodeData = $this->promoCodeDataFactory->create();
$promoCodeData->code = 'test100';
$promoCodeData->discountType = PromoCode::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->discountType = PromoCodeTypeEnum::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->domainId = $domainId;
$promoCode = $this->promoCodeFacade->create($promoCodeData);
$this->setDefaultNominalLimit($promoCode);

$this->createFreeTransportAndPaymentPromoCode($domainId);

$this->loadForOtherDomains();
}

Expand All @@ -156,10 +160,12 @@ private function loadForOtherDomains(): void

$promoCodeData = $this->promoCodeDataFactory->create();
$promoCodeData->code = 'test100';
$promoCodeData->discountType = PromoCode::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->discountType = PromoCodeTypeEnum::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->domainId = $domainId;
$promoCode = $this->promoCodeFacade->create($promoCodeData);
$this->setDefaultNominalLimit($promoCode);

$this->createFreeTransportAndPaymentPromoCode($domainId);
}
}

Expand Down Expand Up @@ -196,4 +202,17 @@ private function setDefaultNominalLimit(PromoCode $promoCode): void
$this->em->persist($promoCodeLimit);
$this->em->flush();
}

/**
* @param int $domainId
*/
private function createFreeTransportAndPaymentPromoCode(int $domainId): void
{
$promoCodeData = $this->promoCodeDataFactory->create();
$promoCodeData->code = 'free-transport';
$promoCodeData->domainId = $domainId;
$promoCodeData->discountType = PromoCodeTypeEnum::DISCOUNT_TYPE_FREE_TRANSPORT_PAYMENT;
$promoCode = $this->promoCodeFacade->create($promoCodeData);
$this->addReferenceForDomain(self::PROMO_CODE_FOR_FREE_TRANSPORT_PAYMENT, $promoCode, $domainId);
}
}
3 changes: 2 additions & 1 deletion app/src/Model/Order/PlaceOrderFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
* @method fillOrderItems(\App\Model\Order\Order $order, \App\Model\Order\OrderData $orderData)
* @property \App\Model\Order\Mail\OrderMailFacade $orderMailFacade
* @property \App\Model\Customer\User\CustomerUserFacade $customerUserFacade
* @method __construct(\Shopsys\FrameworkBundle\Model\Order\Status\OrderStatusRepository $orderStatusRepository, \Shopsys\FrameworkBundle\Model\Order\OrderNumberSequenceRepository $orderNumberSequenceRepository, \Shopsys\FrameworkBundle\Model\Order\OrderHashGeneratorRepository $orderHashGeneratorRepository, \Shopsys\FrameworkBundle\Model\Order\OrderFactory $orderFactory, \Doctrine\ORM\EntityManagerInterface $em, \App\Model\Order\Item\OrderItemFactory $orderItemFactory, \App\Model\Order\Mail\OrderMailFacade $orderMailFacade, \Shopsys\FrameworkBundle\Model\Order\Messenger\PlacedOrderMessageDispatcher $placedOrderMessageDispatcher, \Shopsys\FrameworkBundle\Model\Newsletter\NewsletterFacade $newsletterFacade, \App\Model\Customer\User\CustomerUserFacade $customerUserFacade)
* @method __construct(\Shopsys\FrameworkBundle\Model\Order\Status\OrderStatusRepository $orderStatusRepository, \Shopsys\FrameworkBundle\Model\Order\OrderNumberSequenceRepository $orderNumberSequenceRepository, \Shopsys\FrameworkBundle\Model\Order\OrderHashGeneratorRepository $orderHashGeneratorRepository, \Shopsys\FrameworkBundle\Model\Order\OrderFactory $orderFactory, \Doctrine\ORM\EntityManagerInterface $em, \App\Model\Order\Item\OrderItemFactory $orderItemFactory, \App\Model\Order\Mail\OrderMailFacade $orderMailFacade, \Shopsys\FrameworkBundle\Model\Order\Messenger\PlacedOrderMessageDispatcher $placedOrderMessageDispatcher, \Shopsys\FrameworkBundle\Model\Newsletter\NewsletterFacade $newsletterFacade, \App\Model\Customer\User\CustomerUserFacade $customerUserFacade, \App\Model\Order\PromoCode\PromoCodeFacade $promoCodeFacade)
* @method \App\Model\Order\Order createOrderOnly(\App\Model\Order\OrderData $orderData)
* @method \App\Model\Order\Item\OrderItem enhanceSpecificOrderItem(\App\Model\Order\Item\OrderItem $orderItem, \App\Model\Order\Item\OrderItemData $orderItemData)
* @method \App\Model\Order\Item\OrderItem createSpecificOrderItem(\App\Model\Order\Item\OrderItemData $orderItemData, \App\Model\Order\Order $order)
* @method string generateCacheKey(\App\Model\Order\Item\OrderItemData $orderItemData)
* @property \App\Model\Order\PromoCode\PromoCodeFacade $promoCodeFacade
*/
class PlaceOrderFacade extends BasePlaceOrderFacade
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeFlag\PromoCodeFlag;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeFlag\PromoCodeFlagFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeLimit\PromoCodeLimitFactory;
use Shopsys\FrameworkBundle\Model\Order\PromoCode\PromoCodeTypeEnum;
use Tests\App\Test\TransactionFunctionalTestCase;

class FilterProductByPromoCodeFlagsTest extends TransactionFunctionalTestCase
Expand Down Expand Up @@ -170,7 +171,7 @@ private function createPromoCodeWithFlags(array $promoCodeFlags): PromoCode
$promoCodeData->flags = $promoCodeFlags;
$promoCodeData->domainId = $this->domain->getId();
$promoCodeData->code = 'present';
$promoCodeData->discountType = PromoCode::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->discountType = PromoCodeTypeEnum::DISCOUNT_TYPE_NOMINAL;
$promoCodeData->limits = [$promoCodeLimit];

return $this->promoCodeFacade->create($promoCodeData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Functional\Model\Transport;

use App\DataFixtures\Demo\SettingValueDataFixture;
use App\DataFixtures\Demo\TransportDataFixture;
use App\Model\Transport\Transport;
use PHPUnit\Framework\Attributes\DataProvider;
Expand Down Expand Up @@ -34,7 +35,7 @@ public function testCalculatePriceThrowsExceptionWhenWeightLimitIsExceeded(): vo
{
$transportCzechPost = $this->getReference(TransportDataFixture::TRANSPORT_CZECH_POST, Transport::class);
$this->expectException(TransportPriceNotFoundException::class);
$this->transportPriceCalculation->calculatePrice($transportCzechPost, Price::zero(), Domain::FIRST_DOMAIN_ID, self::CART_TOTAL_WEIGHT_ABOVE_ALL_LIMITS);
$this->transportPriceCalculation->calculatePrice($transportCzechPost, Price::zero(), Domain::FIRST_DOMAIN_ID, self::CART_TOTAL_WEIGHT_ABOVE_ALL_LIMITS, false);
}

/**
Expand All @@ -46,7 +47,7 @@ public function testCalculatePrice(int $cartTotalWeight, int $expectedMoneyAmoun
{
$transportCzechPost = $this->getReference(TransportDataFixture::TRANSPORT_CZECH_POST, Transport::class);

$calculatedPrice = $this->transportPriceCalculation->calculatePrice($transportCzechPost, Price::zero(), Domain::FIRST_DOMAIN_ID, $cartTotalWeight);
$calculatedPrice = $this->transportPriceCalculation->calculatePrice($transportCzechPost, Price::zero(), Domain::FIRST_DOMAIN_ID, $cartTotalWeight, false);

$expectedTransportPriceWithoutVat = $this->priceConverter->convertPriceWithoutVatToDomainDefaultCurrencyPrice(
Money::create($expectedMoneyAmountWithoutVat),
Expand All @@ -73,4 +74,34 @@ public static function calculatePriceDataProvider(): array
],
];
}

/**
* @param \Shopsys\FrameworkBundle\Model\Pricing\Price $productsPrice
* @param bool $forceFreeTransport
*/
#[DataProvider('calculateFreePriceDataProvider')]
public function testCalculateFreePrice(Price $productsPrice, bool $forceFreeTransport): void
{
$transportCzechPost = $this->getReference(TransportDataFixture::TRANSPORT_CZECH_POST, Transport::class);

$calculatedPrice = $this->transportPriceCalculation->calculatePrice($transportCzechPost, $productsPrice, Domain::FIRST_DOMAIN_ID, 0, $forceFreeTransport);

$this->assertTrue($calculatedPrice->getPriceWithoutVat()->isZero());
}

/**
* @return iterable
*/
public static function calculateFreePriceDataProvider(): iterable
{
yield 'products price reached the free price limit' => [
'productsPrice' => new Price(Money::create(SettingValueDataFixture::FREE_TRANSPORT_AND_PAYMENT_LIMIT), Money::create(SettingValueDataFixture::FREE_TRANSPORT_AND_PAYMENT_LIMIT)),
'forceFreeTransport' => false,
];

yield 'free transport price is forced' => [
'productsPrice' => new Price(Money::create(1), Money::create(1)),
'forceFreeTransport' => true,
];
}
}
Loading

0 comments on commit 43cf620

Please sign in to comment.