1515use WooCommerce \PayPalCommerce \StoreSync \Helper \CartHelper ;
1616use WooCommerce \PayPalCommerce \StoreSync \Helper \ProductManager ;
1717use WooCommerce \PayPalCommerce \StoreSync \Schema \PayPalCart ;
18+ use WooCommerce \PayPalCommerce \StoreSync \Validation \Context \IssueContext ;
19+ use WooCommerce \PayPalCommerce \StoreSync \Validation \Context \PricingErrorContext ;
1820
1921/**
2022 * Builds context data for coupon validation issues.
@@ -44,11 +46,11 @@ public function __construct( ProductManager $product_manager, DiscountCalculator
4446 * Builds context by calling declared context builders.
4547 *
4648 * @param string $issue_type The issue type.
47- * @param string $code The coupon code.
48- * @param PayPalCart $cart The cart context.
49- * @param WC_Coupon|null $wc_coupon The WC coupon object.
50- * @param array $builders Array of builder names to call.
51- * @param array $extra Extra context data.
49+ * @param string $code The coupon code.
50+ * @param PayPalCart $cart The cart context.
51+ * @param WC_Coupon|null $wc_coupon The WC coupon object.
52+ * @param array $builders Array of builder names to call.
53+ * @param array $extra Extra context data.
5254 * @return array The built context.
5355 */
5456 public function build_coupon_context (
@@ -75,11 +77,11 @@ public function build_coupon_context(
7577 /**
7678 * Dispatches to the appropriate builder method.
7779 *
78- * @param string $builder The builder name.
79- * @param string $code The coupon code.
80- * @param PayPalCart $cart The cart context.
80+ * @param string $builder The builder name.
81+ * @param string $code The coupon code.
82+ * @param PayPalCart $cart The cart context.
8183 * @param WC_Coupon|null $wc_coupon The WC coupon object.
82- * @param array $extra Extra context data.
84+ * @param array $extra Extra context data.
8385 * @return array The context data from the builder.
8486 */
8587 private function call_builder ( string $ builder , string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -108,10 +110,10 @@ private function call_builder( string $builder, string $code, PayPalCart $cart,
108110 /**
109111 * Builds alternative coupons context.
110112 *
111- * @param string $code The coupon code.
112- * @param PayPalCart $cart The cart context.
113+ * @param string $code The coupon code.
114+ * @param PayPalCart $cart The cart context.
113115 * @param WC_Coupon|null $wc_coupon The WC coupon object.
114- * @param array $extra Extra context data.
116+ * @param array $extra Extra context data.
115117 * @return array The context data.
116118 */
117119 private function build_alternatives ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -130,10 +132,10 @@ private function build_alternatives( string $code, PayPalCart $cart, ?WC_Coupon
130132 /**
131133 * Builds expiration context.
132134 *
133- * @param string $code The coupon code.
134- * @param PayPalCart $cart The cart context.
135+ * @param string $code The coupon code.
136+ * @param PayPalCart $cart The cart context.
135137 * @param WC_Coupon|null $wc_coupon The WC coupon object.
136- * @param array $extra Extra context data.
138+ * @param array $extra Extra context data.
137139 * @return array The context data.
138140 */
139141 private function build_expiration ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -147,17 +149,17 @@ private function build_expiration( string $code, PayPalCart $cart, ?WC_Coupon $w
147149 }
148150
149151 return array (
150- 'expiration_date ' => $ expiration_date ->format ( ' c ' ),
152+ 'expiration_date ' => $ expiration_date ->getTimestamp ( ),
151153 );
152154 }
153155
154156 /**
155157 * Builds usage limits context.
156158 *
157- * @param string $code The coupon code.
158- * @param PayPalCart $cart The cart context.
159+ * @param string $code The coupon code.
160+ * @param PayPalCart $cart The cart context.
159161 * @param WC_Coupon|null $wc_coupon The WC coupon object.
160- * @param array $extra Extra context data.
162+ * @param array $extra Extra context data.
161163 * @return array The context data.
162164 */
163165 private function build_usage_limits ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -174,10 +176,10 @@ private function build_usage_limits( string $code, PayPalCart $cart, ?WC_Coupon
174176 /**
175177 * Builds minimum spend context.
176178 *
177- * @param string $code The coupon code.
178- * @param PayPalCart $cart The cart context.
179+ * @param string $code The coupon code.
180+ * @param PayPalCart $cart The cart context.
179181 * @param WC_Coupon|null $wc_coupon The WC coupon object.
180- * @param array $extra Extra context data.
182+ * @param array $extra Extra context data.
181183 * @return array The context data.
182184 */
183185 private function build_minimum_spend ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -201,10 +203,10 @@ private function build_minimum_spend( string $code, PayPalCart $cart, ?WC_Coupon
201203 /**
202204 * Builds maximum spend context.
203205 *
204- * @param string $code The coupon code.
205- * @param PayPalCart $cart The cart context.
206+ * @param string $code The coupon code.
207+ * @param PayPalCart $cart The cart context.
206208 * @param WC_Coupon|null $wc_coupon The WC coupon object.
207- * @param array $extra Extra context data.
209+ * @param array $extra Extra context data.
208210 * @return array The context data.
209211 */
210212 private function build_maximum_spend ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -226,10 +228,10 @@ private function build_maximum_spend( string $code, PayPalCart $cart, ?WC_Coupon
226228 /**
227229 * Builds eligible items context.
228230 *
229- * @param string $code The coupon code.
230- * @param PayPalCart $cart The cart context.
231+ * @param string $code The coupon code.
232+ * @param PayPalCart $cart The cart context.
231233 * @param WC_Coupon|null $wc_coupon The WC coupon object.
232- * @param array $extra Extra context data.
234+ * @param array $extra Extra context data.
233235 * @return array The context data.
234236 */
235237 private function build_eligible_items ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -249,10 +251,10 @@ private function build_eligible_items( string $code, PayPalCart $cart, ?WC_Coupo
249251 /**
250252 * Builds stacking conflict context.
251253 *
252- * @param string $code The coupon code.
253- * @param PayPalCart $cart The cart context.
254+ * @param string $code The coupon code.
255+ * @param PayPalCart $cart The cart context.
254256 * @param WC_Coupon|null $wc_coupon The WC coupon object.
255- * @param array $extra Extra context data.
257+ * @param array $extra Extra context data.
256258 * @return array The context data.
257259 */
258260 private function build_stacking ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -285,10 +287,10 @@ private function build_stacking( string $code, PayPalCart $cart, ?WC_Coupon $wc_
285287 /**
286288 * Builds email restriction context.
287289 *
288- * @param string $code The coupon code.
289- * @param PayPalCart $cart The cart context.
290+ * @param string $code The coupon code.
291+ * @param PayPalCart $cart The cart context.
290292 * @param WC_Coupon|null $wc_coupon The WC coupon object.
291- * @param array $extra Extra context data.
293+ * @param array $extra Extra context data.
292294 * @return array The context data.
293295 */
294296 private function build_email_restriction ( string $ code , PayPalCart $ cart , ?WC_Coupon $ wc_coupon , array $ extra ): array {
@@ -309,8 +311,8 @@ private function build_email_restriction( string $code, PayPalCart $cart, ?WC_Co
309311 * Gets alternative coupon suggestions via filter.
310312 *
311313 * @param string $failed_code The coupon code that failed.
312- * @param string $reason The failure reason.
313- * @param PayPalCart $cart The cart context.
314+ * @param string $reason The failure reason.
315+ * @param PayPalCart $cart The cart context.
314316 * @return array Array of alternative coupon codes.
315317 */
316318 private function get_alternative_coupons ( string $ failed_code , string $ reason , PayPalCart $ cart ): array {
@@ -323,6 +325,68 @@ private function get_alternative_coupons( string $failed_code, string $reason, P
323325 );
324326 }
325327
328+ /**
329+ * Builds a typed IssueContext instance from a resolved context array.
330+ *
331+ * Returns null for issue types that have no matching context class.
332+ *
333+ * @param string $issue_type The coupon issue type (e.g. 'COUPON_EXPIRED').
334+ * @param string $coupon_code The coupon code that triggered the issue.
335+ * @param array $args The flat context array built by build_coupon_context().
336+ * @return IssueContext|null
337+ */
338+ public function build_coupon_issue_context ( string $ issue_type , string $ coupon_code , array $ args ): ?IssueContext {
339+ $ context = null ;
340+ switch ( $ issue_type ) {
341+ case 'COUPON_EXPIRED ' :
342+ $ context = PricingErrorContext::create_discount_expired ();
343+ break ;
344+
345+ case 'USAGE_LIMIT_EXCEEDED ' :
346+ $ context = PricingErrorContext::create_discount_usage_limit_exceeded ();
347+ break ;
348+
349+ case 'MINIMUM_ORDER_NOT_MET ' :
350+ $ context = PricingErrorContext::create_discount_minimum_not_met ();
351+ break ;
352+
353+ case 'COUPON_NOT_APPLICABLE ' :
354+ case 'COUPON_EMAIL_RESTRICTED ' :
355+ $ context = PricingErrorContext::create_discount_customer_ineligible ();
356+ break ;
357+
358+ case 'COUPON_STACKING_NOT_ALLOWED ' :
359+ $ context = PricingErrorContext::create_promotional_conflict ();
360+ break ;
361+ }
362+
363+ if ( ! $ context ) {
364+ return null ;
365+ }
366+
367+ $ context ->coupon_code ( $ coupon_code );
368+ if ( isset ( $ args ['expiration_date ' ] ) ) {
369+ $ context ->expiration_date ( (int ) $ args ['expiration_date ' ] );
370+ }
371+ if ( isset ( $ args ['usage_limit ' ] ) && is_numeric ( $ args ['usage_limit ' ] ) ) {
372+ $ context ->usage_limit ( (int ) $ args ['usage_limit ' ] );
373+ }
374+ if ( isset ( $ args ['minimum_required ' ] ) ) {
375+ $ context ->minimum_order_amount ( (string ) $ args ['minimum_required ' ] );
376+ }
377+ if ( isset ( $ args ['current_usage ' ] ) ) {
378+ $ context ->current_usage ( (int ) $ args ['current_usage ' ] );
379+ }
380+ if ( isset ( $ args ['currency_code ' ] ) ) {
381+ $ context ->currency_code ( (string ) $ args ['currency_code ' ] );
382+ }
383+ if ( isset ( $ args ['current_discount ' ] ) ) {
384+ $ context ->discount_amount ( (string ) $ args ['current_discount ' ] );
385+ }
386+
387+ return $ context ;
388+ }
389+
326390 /**
327391 * Gets eligible items for a coupon via filter.
328392 *
@@ -331,7 +395,7 @@ private function get_alternative_coupons( string $failed_code, string $reason, P
331395 * excluded items, sale items, and third-party plugin logic.
332396 *
333397 * @param WC_Coupon $wc_coupon The WC coupon.
334- * @param PayPalCart $cart The cart context.
398+ * @param PayPalCart $cart The cart context.
335399 * @return array Array of eligible variant IDs.
336400 */
337401 private function get_eligible_items ( WC_Coupon $ wc_coupon , PayPalCart $ cart ): array {
0 commit comments