PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
← All changes | app/Services/BulkProductInsertService.php +60 -10 1.4.0 → 1.6.5 View file →
@@ -3,11 +3,14 @@
3 3 namespace FluentCart\App\Services;
4 4
5 5 use FluentCart\Api\Resource\ProductVariationResource;
6 6 use FluentCart\App\CPT\FluentProducts;
7 +use FluentCart\App\Helpers\Helper;
7 8 use FluentCart\App\Models\ProductDetail;
8 9 use FluentCart\App\Models\ProductVariation;
9 10 use FluentCart\Framework\Support\Arr;
11 +use FluentCart\App\Http\Rules\RequiredWhenRule;
12 +use FluentCart\App\Http\Rules\WhenFilledRule;
10 13 use FluentCart\Framework\Validator\Validator;
11 14
12 15 class BulkProductInsertService
13 16 {
@@ -103,13 +106,60 @@
103 106 },
104 107 ],
105 108 'variants.*.other_info' => 'required|array',
106 109 'variants.*.other_info.payment_type' => 'required|sanitizeText|in:onetime,subscription',
107 - 'variants.*.other_info.repeat_interval' => 'nullable|required_if:variants.*.other_info.payment_type,subscription|sanitizeText|in:yearly,half_yearly,quarterly,monthly,weekly,daily',
110 + 'variants.*.other_info.times' => [
111 + function ($attribute, $value, $rules, $allData) {
112 + $index = explode('.', $attribute)[1];
113 +
114 + return Helper::installmentTimesError(Arr::get($allData, "variants.$index.other_info"));
115 + },
116 + ],
117 + // Conditional requirements here are closures, not `required_if`, and
118 + // the attributes carrying one have no `nullable`: filterExcludeables()
119 + // drops EVERY rule — closures included — when `nullable` meets a falsy
120 + // value, which is what left these requirements dead. WhenFilledRule
121 + // therefore carries the value checks that `nullable` used to guard.
122 + //
123 + // manage_setup_fee keeps `nullable` on purpose: it is an optional flag
124 + // that both services already default to 'no', so demanding it would
125 + // reject payloads that simply omit it.
126 + 'variants.*.other_info.repeat_interval' => [
127 + RequiredWhenRule::make(
128 + 'variants.*.other_info.payment_type',
129 + 'subscription',
130 + __('Interval is required for subscriptions.', 'fluent-cart')
131 + ),
132 + WhenFilledRule::in(
133 + ['yearly', 'half_yearly', 'quarterly', 'monthly', 'weekly', 'daily'],
134 + __('Interval must be a valid frequency.', 'fluent-cart')
135 + ),
136 + ],
108 137 'variants.*.other_info.trial_days' => 'nullable|numeric|min:0|max:365',
109 - 'variants.*.other_info.manage_setup_fee' => 'nullable|required_if:variants.*.other_info.payment_type,subscription|sanitizeText|in:no,yes',
110 - 'variants.*.other_info.signup_fee' => 'nullable|required_if:variants.*.other_info.manage_setup_fee,yes|numeric|min:0',
111 - 'variants.*.other_info.signup_fee_name' => 'nullable|required_if:variants.*.other_info.manage_setup_fee,yes|sanitizeText|maxLength:100',
138 + 'variants.*.other_info.manage_setup_fee' => 'nullable|sanitizeText|in:no,yes',
139 + 'variants.*.other_info.signup_fee' => [
140 + RequiredWhenRule::make(
141 + 'variants.*.other_info.manage_setup_fee',
142 + 'yes',
143 + __('Setup Fee Amount is required.', 'fluent-cart')
144 + ),
145 + WhenFilledRule::numericAtLeast(
146 + 0,
147 + __('Setup Fee must be a number.', 'fluent-cart'),
148 + __('Setup Fee must be 0 or more.', 'fluent-cart')
149 + ),
150 + ],
151 + 'variants.*.other_info.signup_fee_name' => [
152 + RequiredWhenRule::make(
153 + 'variants.*.other_info.manage_setup_fee',
154 + 'yes',
155 + __('Setup Fee Name is required.', 'fluent-cart')
156 + ),
157 + WhenFilledRule::text(
158 + 100,
159 + __('Setup Fee Name must be plain text of 100 characters or fewer.', 'fluent-cart')
160 + ),
161 + ],
112 162 ];
113 163
114 164 $messages = [
115 165 'post_title.required' => __('Title is required.', 'fluent-cart'),
@@ -126,17 +176,12 @@
126 176 'variants.*.item_price.numeric' => __('Price must be a number.', 'fluent-cart'),
127 177 'variants.*.item_price.min' => __('Price must be a positive number.', 'fluent-cart'),
128 178 'variants.*.other_info.payment_type.required' => __('Payment Type is required.', 'fluent-cart'),
129 179 'variants.*.other_info.payment_type.in' => __('Payment Type must be onetime or subscription.', 'fluent-cart'),
130 - 'variants.*.other_info.repeat_interval.required_if' => __('Interval is required for subscriptions.', 'fluent-cart'),
131 - 'variants.*.other_info.repeat_interval.in' => __('Interval must be a valid frequency.', 'fluent-cart'),
132 180 'variants.*.other_info.trial_days.numeric' => __('Trial days must be a number.', 'fluent-cart'),
133 181 'variants.*.other_info.trial_days.min' => __('Trial days must be 0 or more.', 'fluent-cart'),
134 182 'variants.*.other_info.trial_days.max' => __('Trial days may not be greater than 365.', 'fluent-cart'),
135 183 'variants.*.other_info.manage_setup_fee.in' => __('Setup fee option must be yes or no.', 'fluent-cart'),
136 - 'variants.*.other_info.signup_fee.required_if' => __('Setup Fee Amount is required.', 'fluent-cart'),
137 - 'variants.*.other_info.signup_fee.numeric' => __('Setup Fee must be a number.', 'fluent-cart'),
138 - 'variants.*.other_info.signup_fee_name.required_if' => __('Setup Fee Name is required.', 'fluent-cart'),
139 184 ];
140 185
141 186 $validator = Validator::make($data, $rules, $messages);
142 187
@@ -486,13 +531,18 @@
486 531 }
487 532
488 533 /**
489 534 * Sanitize a price value to ensure it's a valid integer (cents).
535 + *
536 + * The value ARRIVES in cents — this only normalizes float artifacts and
537 + * rejects negatives. CSV imports carry dollars, so Importer.vue converts
538 + * at parse time, keeping this endpoint on the same cents contract as every
539 + * other write. See dev-docs/PRICING-AND-TAX.md §6.
490 540 */
491 541 protected function sanitizePrice($value): int
492 542 {
493 543 if (is_numeric($value)) {
494 - return absint(round(floatval($value) * 100));
544 + return absint(Helper::roundCent($value));
495 545 }
496 546
497 547 return 0;
498 548 }