Skip to content

Commit a6131a2

Browse files
Merge remote-tracking branch 'adobe-commerce-tier-4/ACP2E-3139' into Tier4-PR-2024-08-05
2 parents cc78d0a + 2f85903 commit a6131a2

File tree

2 files changed

+237
-0
lines changed

2 files changed

+237
-0
lines changed

app/code/Magento/SalesRule/Model/Quote/Discount.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,21 @@ public function collect(
197197
if ($item->getNoDiscount() || !$this->calculator->canApplyDiscount($item) || $item->getParentItem()) {
198198
continue;
199199
}
200+
201+
switch ($rule->getSimpleAction()) {
202+
case Rule::BY_PERCENT_ACTION:
203+
case Rule::BY_FIXED_ACTION:
204+
if ($rule->getDiscountStep() > $item->getQty()) {
205+
continue 2;
206+
}
207+
break;
208+
case Rule::BUY_X_GET_Y_ACTION:
209+
if ($rule->getDiscountStep() >= $item->getQty()) {
210+
continue 2;
211+
}
212+
break;
213+
}
214+
200215
$eventArgs['item'] = $item;
201216
$this->eventManager->dispatch('sales_quote_address_discount_item', $eventArgs);
202217

dev/tests/integration/testsuite/Magento/SalesRule/Model/Quote/DiscountTest.php

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,4 +485,226 @@ public function testFixedAmountWholeCartDiscountOnBundleProduct(): void
485485
$this->assertEquals(32.5, $quote->getSubtotalWithDiscount());
486486
$this->assertEquals(82.5, $quote->getSubtotal());
487487
}
488+
489+
/**
490+
* @return void
491+
* @throws NoSuchEntityException
492+
*/
493+
#[
494+
DataFixture(CategoryFixture::class, as: 'c1'),
495+
DataFixture(ProductFixture::class, [
496+
'price' => 123,
497+
'sku' => 'p1',
498+
'category_ids' => ['$c1.id$']
499+
], 'p1'),
500+
DataFixture(
501+
RuleFixture::class,
502+
[
503+
'stop_rules_processing'=> 0,
504+
'discount_amount' => 10,
505+
'simple_action' => Rule::BY_FIXED_ACTION,
506+
'sort_order' => 0
507+
],
508+
'rule1'
509+
),
510+
DataFixture(
511+
RuleFixture::class,
512+
[
513+
'stop_rules_processing'=> 0,
514+
'discount_amount' => 20,
515+
'simple_action' => Rule::BY_PERCENT_ACTION,
516+
'discount_step' => 3,
517+
'sort_order' => 2
518+
],
519+
'rule2'
520+
),
521+
DataFixture(
522+
RuleFixture::class,
523+
[
524+
'discount_amount' => 3,
525+
'simple_action' => Rule::BUY_X_GET_Y_ACTION,
526+
'discount_step' => 5,
527+
'sort_order' => 4
528+
],
529+
'rule3'
530+
),
531+
DataFixture(GuestCartFixture::class, as: 'cart1'),
532+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart1.id$', 'product_id' => '$p1.id$']),
533+
DataFixture(GuestCartFixture::class, as: 'cart2'),
534+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart2.id$', 'product_id' => '$p1.id$', 'qty' => 3]),
535+
DataFixture(GuestCartFixture::class, as: 'cart3'),
536+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart3.id$', 'product_id' => '$p1.id$', 'qty' => 9]),
537+
]
538+
public function testDiscountOnSimpleProductWhenFurtherRulesHaveDiscountQtyStepSpecified(): void
539+
{
540+
$cart1Id = (int)$this->fixtures->get('cart1')->getId();
541+
$cart2Id = (int)$this->fixtures->get('cart2')->getId();
542+
$cart3Id = (int)$this->fixtures->get('cart3')->getId();
543+
$quote1 = $this->quote->get($cart1Id);
544+
$quote2 = $this->quote->get($cart2Id);
545+
$quote3 = $this->quote->get($cart3Id);
546+
$rule1Id = (int)$this->fixtures->get('rule1')->getId();
547+
$rule2Id = (int)$this->fixtures->get('rule2')->getId();
548+
$rule3Id = (int)$this->fixtures->get('rule3')->getId();
549+
550+
$quote1->setStoreId(1)->setIsActive(true);
551+
$address = $quote1->getShippingAddress();
552+
$this->shipping->setAddress($address);
553+
$this->shippingAssignment->setShipping($this->shipping);
554+
$this->shippingAssignment->setItems($address->getAllItems());
555+
556+
$this->subtotalCollector->collect($quote1, $this->shippingAssignment, $this->total);
557+
$this->discountCollector->collect($quote1, $this->shippingAssignment, $this->total);
558+
559+
$this->assertEquals(-10, $this->total->getDiscountAmount());
560+
$this->assertEqualsCanonicalizing([$rule1Id], explode(',', $quote1->getAppliedRuleIds()));
561+
562+
$quote2->setStoreId(1)->setIsActive(true);
563+
$address = $quote2->getShippingAddress();
564+
$this->shipping->setAddress($address);
565+
$this->shippingAssignment->setShipping($this->shipping);
566+
$this->shippingAssignment->setItems($address->getAllItems());
567+
568+
$this->subtotalCollector->collect($quote2, $this->shippingAssignment, $this->total);
569+
$this->discountCollector->collect($quote2, $this->shippingAssignment, $this->total);
570+
571+
$this->assertEquals(-97.8, $this->total->getDiscountAmount());
572+
$this->assertEqualsCanonicalizing([$rule1Id,$rule2Id], explode(',', $quote2->getAppliedRuleIds()));
573+
574+
$quote3->setStoreId(1)->setIsActive(true);
575+
$address = $quote3->getShippingAddress();
576+
$this->shipping->setAddress($address);
577+
$this->shippingAssignment->setShipping($this->shipping);
578+
$this->shippingAssignment->setItems($address->getAllItems());
579+
580+
$this->subtotalCollector->collect($quote3, $this->shippingAssignment, $this->total);
581+
$this->discountCollector->collect($quote3, $this->shippingAssignment, $this->total);
582+
583+
$this->assertEquals(-662.4, $this->total->getDiscountAmount());
584+
$this->assertEqualsCanonicalizing([$rule1Id,$rule2Id,$rule3Id], explode(',', $quote3->getAppliedRuleIds()));
585+
}
586+
587+
/**
588+
* @return void
589+
* @throws NoSuchEntityException
590+
*/
591+
#[
592+
DataFixture(CategoryFixture::class, as: 'c1'),
593+
DataFixture(ProductFixture::class, [
594+
'price' => 123,
595+
'sku' => 'p1',
596+
'category_ids' => ['$c1.id$']
597+
], 'p1'),
598+
DataFixture(
599+
RuleFixture::class,
600+
[
601+
'stop_rules_processing'=> 0,
602+
'discount_amount' => 33,
603+
'simple_action' => Rule::CART_FIXED_ACTION,
604+
'discount_step' => 3,
605+
'sort_order' => 0
606+
],
607+
'rule1'
608+
),
609+
DataFixture(GuestCartFixture::class, as: 'cart1'),
610+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart1.id$', 'product_id' => '$p1.id$']),
611+
DataFixture(GuestCartFixture::class, as: 'cart2'),
612+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart2.id$', 'product_id' => '$p1.id$', 'qty' => 5]),
613+
]
614+
public function testFixedAmountDiscountForWholeCartOnSimpleProductWhenStepQtyIsSpecified(): void
615+
{
616+
$cart1Id = (int)$this->fixtures->get('cart1')->getId();
617+
$cart2Id = (int)$this->fixtures->get('cart2')->getId();
618+
$quote1 = $this->quote->get($cart1Id);
619+
$quote2 = $this->quote->get($cart2Id);
620+
$rule1Id = (int)$this->fixtures->get('rule1')->getId();
621+
622+
$quote1->setStoreId(1)->setIsActive(true);
623+
$address = $quote1->getShippingAddress();
624+
$this->shipping->setAddress($address);
625+
$this->shippingAssignment->setShipping($this->shipping);
626+
$this->shippingAssignment->setItems($address->getAllItems());
627+
628+
$this->subtotalCollector->collect($quote1, $this->shippingAssignment, $this->total);
629+
$this->discountCollector->collect($quote1, $this->shippingAssignment, $this->total);
630+
631+
$this->assertEquals(-33, $this->total->getDiscountAmount());
632+
$this->assertEqualsCanonicalizing([$rule1Id], explode(',', $quote1->getAppliedRuleIds()));
633+
634+
$quote2->setStoreId(1)->setIsActive(true);
635+
$address = $quote2->getShippingAddress();
636+
$this->shipping->setAddress($address);
637+
$this->shippingAssignment->setShipping($this->shipping);
638+
$this->shippingAssignment->setItems($address->getAllItems());
639+
640+
$this->subtotalCollector->collect($quote2, $this->shippingAssignment, $this->total);
641+
$this->discountCollector->collect($quote2, $this->shippingAssignment, $this->total);
642+
643+
$this->assertEquals(-33, $this->total->getDiscountAmount());
644+
$this->assertEqualsCanonicalizing([$rule1Id], explode(',', $quote2->getAppliedRuleIds()));
645+
}
646+
647+
/**
648+
* @return void
649+
* @throws NoSuchEntityException
650+
*/
651+
#[
652+
DataFixture(CategoryFixture::class, as: 'c1'),
653+
DataFixture(
654+
ProductFixture::class,
655+
[
656+
'price' => 123,
657+
'sku' => 'p1',
658+
'category_ids' => ['$c1.id$']
659+
],
660+
'p1'
661+
),
662+
DataFixture(
663+
RuleFixture::class,
664+
[
665+
'discount_amount' => 1,
666+
'simple_action' => Rule::BUY_X_GET_Y_ACTION,
667+
'discount_step' => 3,
668+
],
669+
'rule1'
670+
),
671+
DataFixture(GuestCartFixture::class, as: 'cart1'),
672+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart1.id$', 'product_id' => '$p1.id$', 'qty' => 3]),
673+
DataFixture(GuestCartFixture::class, as: 'cart2'),
674+
DataFixture(AddProductToCartFixture::class, ['cart_id' => '$cart2.id$', 'product_id' => '$p1.id$', 'qty' => 4]),
675+
]
676+
public function testDiscountOnSimpleProductWhenBuyXGetYRuleHasDiscountQtyStepSpecified(): void
677+
{
678+
$cart1Id = (int)$this->fixtures->get('cart1')->getId();
679+
$quote1 = $this->quote->get($cart1Id);
680+
$rule1Id = (int)$this->fixtures->get('rule1')->getId();
681+
682+
$quote1->setStoreId(1)->setIsActive(true);
683+
$address = $quote1->getShippingAddress();
684+
$this->shipping->setAddress($address);
685+
$this->shippingAssignment->setShipping($this->shipping);
686+
$this->shippingAssignment->setItems($address->getAllItems());
687+
688+
$this->subtotalCollector->collect($quote1, $this->shippingAssignment, $this->total);
689+
$this->discountCollector->collect($quote1, $this->shippingAssignment, $this->total);
690+
691+
$this->assertEquals(0, $this->total->getDiscountAmount());
692+
$this->assertNull($quote1->getAppliedRuleIds());
693+
694+
$quote1->addProduct($this->fixtures->get('p1'), 1);
695+
696+
$this->subtotalCollector->collect($quote1, $this->shippingAssignment, $this->total);
697+
$this->discountCollector->collect($quote1, $this->shippingAssignment, $this->total);
698+
699+
$this->assertEquals(-123, $this->total->getDiscountAmount());
700+
$this->assertEqualsCanonicalizing([$rule1Id], explode(',', $quote1->getAppliedRuleIds()));
701+
702+
$quote1->setItemQty($this->fixtures->get('p1')->getId(), 3);
703+
704+
$this->subtotalCollector->collect($quote1, $this->shippingAssignment, $this->total);
705+
$this->discountCollector->collect($quote1, $this->shippingAssignment, $this->total);
706+
707+
$this->assertEquals(-123, $this->total->getDiscountAmount());
708+
$this->assertEqualsCanonicalizing([$rule1Id], explode(',', $quote1->getAppliedRuleIds()));
709+
}
488710
}

0 commit comments

Comments
 (0)