8
8
use Psr \EventDispatcher \EventDispatcherInterface ;
9
9
use Setono \Doctrine \ORMTrait ;
10
10
use Setono \SyliusCatalogPromotionPlugin \Checker \Runtime \RuntimeCheckerInterface ;
11
- use Setono \SyliusCatalogPromotionPlugin \Event \CatalogPromotionAppliedEvent ;
11
+ use Setono \SyliusCatalogPromotionPlugin \Event \CatalogPromotionsAppliedEvent ;
12
12
use Setono \SyliusCatalogPromotionPlugin \Model \CatalogPromotionInterface ;
13
13
use Setono \SyliusCatalogPromotionPlugin \Model \ProductInterface ;
14
14
use Setono \SyliusCatalogPromotionPlugin \Repository \CatalogPromotionRepositoryInterface ;
@@ -17,9 +17,6 @@ final class RuntimePromotionsApplicator implements RuntimePromotionsApplicatorIn
17
17
{
18
18
use ORMTrait;
19
19
20
- /** @var array<string, float> */
21
- private array $ multiplierCache = [];
22
-
23
20
/** @var array<string, CatalogPromotionInterface|null> */
24
21
private array $ catalogPromotionCache = [];
25
22
@@ -34,95 +31,88 @@ public function __construct(
34
31
$ this ->managerRegistry = $ managerRegistry ;
35
32
}
36
33
37
- public function apply (ProductInterface $ product , int $ price , bool $ manuallyDiscounted ): int
34
+ public function apply (ProductInterface $ product , int $ price , int $ originalPrice = null ): int
38
35
{
36
+ $ originalPrice = $ originalPrice ?? $ price ;
37
+ $ manuallyDiscounted = $ price < $ originalPrice ;
38
+
39
39
$ catalogPromotions = $ product ->getPreQualifiedCatalogPromotions ();
40
40
41
41
if ([] === $ catalogPromotions ) {
42
42
return $ price ;
43
43
}
44
44
45
- $ appliedPrice = ( int ) floor ( $ this ->getMultiplier ($ catalogPromotions , $ manuallyDiscounted) * $ price );
46
- if ($ appliedPrice !== $ price ) {
47
- $ this -> eventDispatcher -> dispatch ( new CatalogPromotionAppliedEvent ( $ product ));
48
- }
45
+ $ catalogPromotions = $ this ->provideEligibleCatalogPromotions ($ catalogPromotions , $ manuallyDiscounted );
46
+ foreach ($ catalogPromotions as $ catalogPromotion ) {
47
+ if (! $ catalogPromotion -> isManuallyDiscountedProductsExcluded () && $ catalogPromotion -> isUsingOriginalPriceAsBase ()) {
48
+ $ price = $ originalPrice ;
49
49
50
- return $ appliedPrice ;
51
- }
50
+ break ;
51
+ }
52
+ }
52
53
53
- /**
54
- * @param list<string> $catalogPromotions
55
- */
56
- private function getMultiplier (array $ catalogPromotions , bool $ manuallyDiscounted ): float
57
- {
58
- $ cacheKey = sprintf ('%s%d ' , implode ($ catalogPromotions ), (int ) $ manuallyDiscounted );
54
+ $ multiplier = 1.0 ;
59
55
60
- if (!isset ($ this ->multiplierCache [$ cacheKey ])) {
61
- $ multiplier = 1.0 ;
56
+ $ appliedCatalogPromotions = [];
57
+ foreach ($ catalogPromotions as $ catalogPromotion ) {
58
+ $ multiplier *= 1 - $ catalogPromotion ->getDiscount ();
62
59
63
- foreach ($ this ->getEligibleCatalogPromotions ($ catalogPromotions , $ manuallyDiscounted ) as $ catalogPromotion ) {
64
- $ multiplier *= $ catalogPromotion ->getMultiplier ();
65
- }
60
+ $ appliedCatalogPromotions [] = $ catalogPromotion ;
61
+ }
66
62
67
- $ this ->multiplierCache [$ cacheKey ] = $ multiplier ;
63
+ if ([] !== $ appliedCatalogPromotions ) {
64
+ $ this ->eventDispatcher ->dispatch (new CatalogPromotionsAppliedEvent ($ product , $ appliedCatalogPromotions ));
68
65
}
69
66
70
- return $ this -> multiplierCache [ $ cacheKey ] ;
67
+ return ( int ) floor ( $ price * $ multiplier ) ;
71
68
}
72
69
73
70
/**
74
71
* @param list<string> $catalogPromotions
75
72
*
76
- * @return \Generator<array-key, CatalogPromotionInterface>
73
+ * @return list< CatalogPromotionInterface>
77
74
*/
78
- private function getEligibleCatalogPromotions (array $ catalogPromotions , bool $ manuallyDiscounted ): \ Generator
75
+ private function provideEligibleCatalogPromotions (array $ catalogPromotions , bool $ manuallyDiscounted ): array
79
76
{
80
77
$ eligiblePromotions = [];
81
78
$ eligibleExclusivePromotions = [];
82
79
83
80
foreach ($ catalogPromotions as $ catalogPromotion ) {
84
- $ this ->ensureCatalogPromotionCache ($ catalogPromotion );
85
-
86
- if (null === $ this ->catalogPromotionCache [$ catalogPromotion ]) {
81
+ $ catalogPromotion = $ this ->cacheCatalogPromotion ($ catalogPromotion );
82
+ if (null === $ catalogPromotion ) {
87
83
continue ;
88
84
}
89
85
90
- if ($ manuallyDiscounted && $ this -> catalogPromotionCache [ $ catalogPromotion] ->isManuallyDiscountedProductsExcluded ()) {
86
+ if ($ manuallyDiscounted && $ catalogPromotion ->isManuallyDiscountedProductsExcluded ()) {
91
87
continue ;
92
88
}
93
89
94
- if (!$ this ->runtimeChecker ->isEligible ($ this -> catalogPromotionCache [ $ catalogPromotion] )) {
90
+ if (!$ this ->runtimeChecker ->isEligible ($ catalogPromotion )) {
95
91
continue ;
96
92
}
97
93
98
- $ eligiblePromotions [] = $ this -> catalogPromotionCache [ $ catalogPromotion] ;
94
+ $ eligiblePromotions [] = $ catalogPromotion ;
99
95
100
- if ($ this -> catalogPromotionCache [ $ catalogPromotion] ->isExclusive ()) {
101
- $ eligibleExclusivePromotions [$ this -> catalogPromotionCache [ $ catalogPromotion] ->getPriority ()] = $ this -> catalogPromotionCache [ $ catalogPromotion] ;
96
+ if ($ catalogPromotion ->isExclusive ()) {
97
+ $ eligibleExclusivePromotions [$ catalogPromotion ->getPriority ()] = $ catalogPromotion ;
102
98
}
103
99
}
104
100
105
101
if ([] !== $ eligibleExclusivePromotions ) {
106
102
krsort ($ eligibleExclusivePromotions , \SORT_NUMERIC );
107
- yield reset ($ eligibleExclusivePromotions );
108
- } else {
109
- yield from $ eligiblePromotions ;
103
+
104
+ return [reset ($ eligibleExclusivePromotions )];
110
105
}
106
+
107
+ return $ eligiblePromotions ;
111
108
}
112
109
113
- private function ensureCatalogPromotionCache (string $ catalogPromotion ): void
110
+ private function cacheCatalogPromotion (string $ catalogPromotion ): ? CatalogPromotionInterface
114
111
{
115
- if (array_key_exists ($ catalogPromotion , $ this ->catalogPromotionCache )) {
116
- if (null === $ this ->catalogPromotionCache [$ catalogPromotion ]) {
117
- return ;
118
- }
119
-
120
- // If the entity is still managed, we don't need to do anything
121
- if ($ this ->getManager ($ this ->catalogPromotionClass )->contains ($ this ->catalogPromotionCache [$ catalogPromotion ])) {
122
- return ;
123
- }
112
+ if (!array_key_exists ($ catalogPromotion , $ this ->catalogPromotionCache ) || (null !== $ this ->catalogPromotionCache [$ catalogPromotion ] && !$ this ->getManager ($ this ->catalogPromotionClass )->contains ($ this ->catalogPromotionCache [$ catalogPromotion ]))) {
113
+ $ this ->catalogPromotionCache [$ catalogPromotion ] = $ this ->getRepository ($ this ->catalogPromotionClass , CatalogPromotionRepositoryInterface::class)->findOneByCode ($ catalogPromotion );
124
114
}
125
115
126
- $ this ->catalogPromotionCache [$ catalogPromotion ] = $ this -> getRepository ( $ this -> catalogPromotionClass , CatalogPromotionRepositoryInterface::class)-> findOneByCode ( $ catalogPromotion ) ;
116
+ return $ this ->catalogPromotionCache [$ catalogPromotion ];
127
117
}
128
118
}
0 commit comments