| @@ -2,9 +2,11 @@ | ||
| 2 | 2 | |
| 3 | 3 | namespace FluentCart\Api\Resource; |
| 4 | 4 | |
| 5 | 5 | use FluentCart\App\App; |
| 6 | +use FluentCart\App\Helpers\AttributeHelper; | |
| 6 | 7 | use FluentCart\App\Models\OrderItem; |
| 8 | +use FluentCart\App\Models\ProductVariation; | |
| 7 | 9 | use FluentCart\Framework\Database\Orm\Builder; |
| 8 | 10 | use FluentCart\Framework\Support\Arr; |
| 9 | 11 | use FluentCart\Framework\Support\Collection; |
| 10 | 12 | use FluentCart\Framework\Support\DateTime; |
| @@ -232,13 +234,32 @@ | ||
| 232 | 234 | |
| 233 | 235 | |
| 234 | 236 | if (empty($isExist)) { |
| 235 | 237 | unset($itemData['id']); |
| 238 | + | |
| 239 | + // Snapshot the variant's attribute map + variation type into | |
| 240 | + // other_info so items added on order-edit carry the same data as | |
| 241 | + // the create path (AdminOrderProcessor), not just what the picker sent. | |
| 242 | + $otherInfo = Arr::get($item, 'other_info', []); | |
| 243 | + if (!is_array($otherInfo)) { | |
| 244 | + $otherInfo = []; | |
| 245 | + } | |
| 246 | + if (!array_key_exists('item_attributes', $otherInfo)) { | |
| 247 | + $otherInfo['item_attributes'] = AttributeHelper::getProductItemAttributes($variationId, $productId); | |
| 248 | + } | |
| 249 | + if (empty($otherInfo['variation_type'])) { | |
| 250 | + // Resolve server-side from the variation (same as the create | |
| 251 | + // path) — admin orders don't go through the cart, so the snapshot | |
| 252 | + // is the server's responsibility, not the request's. | |
| 253 | + $variation = ProductVariation::query()->with('product_detail')->find($variationId); | |
| 254 | + $otherInfo['variation_type'] = ($variation && $variation->product_detail) ? (string) $variation->product_detail->variation_type : ''; | |
| 255 | + } | |
| 256 | + | |
| 236 | 257 | $item = wp_parse_args([ |
| 237 | 258 | 'order_id' => $id, |
| 238 | 259 | 'cart_index' => $idx + 1, |
| 239 | 260 | 'fulfillment_type' => $fulfillment_type, |
| 240 | - 'other_info' => json_encode(Arr::get($item, 'other_info', [])), | |
| 261 | + 'other_info' => json_encode($otherInfo), | |
| 241 | 262 | 'payment_type' => Arr::get($item, 'payment_type', Arr::get($item, 'other_info.payment_type', '')), |
| 242 | 263 | 'shipping_charge' => Arr::get($item, 'shipping_charge', 0), |
| 243 | 264 | 'created_at' => DateTime::now(), |
| 244 | 265 | 'updated_at' => DateTime::now(), |
| @@ -315,8 +336,10 @@ | ||
| 315 | 336 | * |
| 316 | 337 | */ |
| 317 | 338 | public static function topProductsSold($params = []) |
| 318 | 339 | { |
| 340 | + $params = is_array($params) ? $params : []; | |
| 341 | + | |
| 319 | 342 | return OrderItem::search(Arr::only($params, ['created_at'])) |
| 320 | 343 | ->select('post_id') |
| 321 | 344 | ->selectRaw('SUM(quantity) as total_sold') |
| 322 | 345 | ->groupBy('post_id') |