| @@ -10,8 +10,10 @@ | ||
| 10 | 10 | use FluentCart\App\Models\ProductVariation; |
| 11 | 11 | use FluentCart\App\Services\Filter\ProductFilter; |
| 12 | 12 | use FluentCart\Framework\Http\Request\Request; |
| 13 | 13 | use FluentCart\Framework\Support\Arr; |
| 14 | +use FluentCart\App\Http\Rules\RequiredWhenRule; | |
| 15 | +use FluentCart\App\Http\Rules\WhenFilledRule; | |
| 14 | 16 | use FluentCart\Framework\Validator\Validator; |
| 15 | 17 | |
| 16 | 18 | class BulkProductUpdateService |
| 17 | 19 | { |
| @@ -205,13 +207,53 @@ | ||
| 205 | 207 | |
| 206 | 208 | return Helper::installmentTimesError(Arr::get($allData, "variants.$index.other_info")); |
| 207 | 209 | }, |
| 208 | 210 | ], |
| 209 | - 'variants.*.other_info.repeat_interval' => 'nullable|required_if:variants.*.other_info.payment_type,subscription|sanitizeText|in:yearly,half_yearly,quarterly,monthly,weekly,daily', | |
| 211 | + // Conditional requirements here are closures, not `required_if`, and | |
| 212 | + // the attributes carrying one have no `nullable`: filterExcludeables() | |
| 213 | + // drops EVERY rule — closures included — when `nullable` meets a falsy | |
| 214 | + // value, which is what left these requirements dead. WhenFilledRule | |
| 215 | + // therefore carries the value checks that `nullable` used to guard. | |
| 216 | + // | |
| 217 | + // manage_setup_fee keeps `nullable` on purpose: it is an optional flag | |
| 218 | + // that both services already default to 'no', so demanding it would | |
| 219 | + // reject payloads that simply omit it. | |
| 220 | + 'variants.*.other_info.repeat_interval' => [ | |
| 221 | + RequiredWhenRule::make( | |
| 222 | + 'variants.*.other_info.payment_type', | |
| 223 | + 'subscription', | |
| 224 | + __('Interval is required for subscriptions.', 'fluent-cart') | |
| 225 | + ), | |
| 226 | + WhenFilledRule::in( | |
| 227 | + ['yearly', 'half_yearly', 'quarterly', 'monthly', 'weekly', 'daily'], | |
| 228 | + __('Interval must be a valid frequency.', 'fluent-cart') | |
| 229 | + ), | |
| 230 | + ], | |
| 210 | 231 | 'variants.*.other_info.trial_days' => 'nullable|numeric|min:0|max:365', |
| 211 | - 'variants.*.other_info.manage_setup_fee' => 'nullable|required_if:variants.*.other_info.payment_type,subscription|sanitizeText|in:no,yes', | |
| 212 | - 'variants.*.other_info.signup_fee' => 'nullable|required_if:variants.*.other_info.manage_setup_fee,yes|numeric|min:0', | |
| 213 | - 'variants.*.other_info.signup_fee_name' => 'nullable|required_if:variants.*.other_info.manage_setup_fee,yes|sanitizeText|maxLength:100', | |
| 232 | + 'variants.*.other_info.manage_setup_fee' => 'nullable|sanitizeText|in:no,yes', | |
| 233 | + 'variants.*.other_info.signup_fee' => [ | |
| 234 | + RequiredWhenRule::make( | |
| 235 | + 'variants.*.other_info.manage_setup_fee', | |
| 236 | + 'yes', | |
| 237 | + __('Setup Fee Amount is required.', 'fluent-cart') | |
| 238 | + ), | |
| 239 | + WhenFilledRule::numericAtLeast( | |
| 240 | + 0, | |
| 241 | + __('Setup Fee must be a number.', 'fluent-cart'), | |
| 242 | + __('Setup Fee must be 0 or more.', 'fluent-cart') | |
| 243 | + ), | |
| 244 | + ], | |
| 245 | + 'variants.*.other_info.signup_fee_name' => [ | |
| 246 | + RequiredWhenRule::make( | |
| 247 | + 'variants.*.other_info.manage_setup_fee', | |
| 248 | + 'yes', | |
| 249 | + __('Setup Fee Name is required.', 'fluent-cart') | |
| 250 | + ), | |
| 251 | + WhenFilledRule::text( | |
| 252 | + 100, | |
| 253 | + __('Setup Fee Name must be plain text of 100 characters or fewer.', 'fluent-cart') | |
| 254 | + ), | |
| 255 | + ], | |
| 214 | 256 | ]; |
| 215 | 257 | |
| 216 | 258 | $messages = [ |
| 217 | 259 | 'post_title.required' => __('Title is required.', 'fluent-cart'), |
| @@ -224,17 +266,12 @@ | ||
| 224 | 266 | 'variants.*.item_price.numeric' => __('Price must be a number.', 'fluent-cart'), |
| 225 | 267 | 'variants.*.item_price.min' => __('Price must be a positive number.', 'fluent-cart'), |
| 226 | 268 | 'variants.*.other_info.payment_type.required' => __('Payment Type is required.', 'fluent-cart'), |
| 227 | 269 | 'variants.*.other_info.payment_type.in' => __('Payment Type must be onetime or subscription.', 'fluent-cart'), |
| 228 | - 'variants.*.other_info.repeat_interval.required_if' => __('Interval is required for subscriptions.', 'fluent-cart'), | |
| 229 | - 'variants.*.other_info.repeat_interval.in' => __('Interval must be a valid frequency.', 'fluent-cart'), | |
| 230 | 270 | 'variants.*.other_info.trial_days.numeric' => __('Trial days must be a number.', 'fluent-cart'), |
| 231 | 271 | 'variants.*.other_info.trial_days.min' => __('Trial days must be 0 or more.', 'fluent-cart'), |
| 232 | 272 | 'variants.*.other_info.trial_days.max' => __('Trial days may not be greater than 365.', 'fluent-cart'), |
| 233 | 273 | 'variants.*.other_info.manage_setup_fee.in' => __('Setup fee option must be yes or no.', 'fluent-cart'), |
| 234 | - 'variants.*.other_info.signup_fee.required_if' => __('Setup Fee Amount is required.', 'fluent-cart'), | |
| 235 | - 'variants.*.other_info.signup_fee.numeric' => __('Setup Fee must be a number.', 'fluent-cart'), | |
| 236 | - 'variants.*.other_info.signup_fee_name.required_if' => __('Setup Fee Name is required.', 'fluent-cart'), | |
| 237 | 274 | ]; |
| 238 | 275 | |
| 239 | 276 | $validator = Validator::make($data, $rules, $messages); |
| 240 | 277 | |