diff --git a/app/Http/Controllers/OrderController.php b/app/Http/Controllers/OrderController.php index fd54ceb..9439f74 100644 --- a/app/Http/Controllers/OrderController.php +++ b/app/Http/Controllers/OrderController.php @@ -478,8 +478,11 @@ public function update(Request $request, Order $order) $totalCommission = 0; // 4. Process NEW Items + $variantIds = collect($validated['items'])->pluck('id'); + $variants = ProductVariant::with('product')->whereIn('id', $variantIds)->get()->keyBy('id'); + foreach ($validated['items'] as $itemData) { - $variant = ProductVariant::with('product')->find($itemData['id']); + $variant = $variants->get($itemData['id']); // Stock Check if ($variant->quantity < $itemData['quantity']) { diff --git a/phpunit.xml b/phpunit.xml index d703241..4216f86 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -19,6 +19,7 @@ + diff --git a/tests/Feature/OrderUpdatePerformanceTest.php b/tests/Feature/OrderUpdatePerformanceTest.php new file mode 100644 index 0000000..ad08546 --- /dev/null +++ b/tests/Feature/OrderUpdatePerformanceTest.php @@ -0,0 +1,120 @@ +create(); + + $category = Category::create(['name' => 'Test Category']); + $unit = Unit::create(['name' => 'Test Unit', 'short_name' => 'tu']); + + $product = Product::create([ + 'name' => 'Test Product', + 'sku' => 'TP-001', + 'category_id' => $category->id, + 'unit_id' => $unit->id, + 'selling_price' => 100, + 'quantity' => 1000, + 'alert_quantity' => 10, + ]); + + $variants = []; + for ($i = 0; $i < 10; $i++) { + $variants[] = ProductVariant::create([ + 'product_id' => $product->id, + 'unit_id' => $unit->id, + 'sku' => 'TP-001-V' . $i, + 'selling_price' => 100, + 'limit_price' => 80, + 'quantity' => 100, // Initial quantity + 'alert_quantity' => 10, + ]); + } + + $customer = Customer::create([ + 'name' => 'Test Customer', + 'mobile' => '1234567890', + 'address' => 'Test Address', + 'city' => 'Test City', + 'country' => 'Sri Lanka', + ]); + + $order = Order::forceCreate([ + 'order_number' => 'ORD-001', + 'user_id' => $user->id, + 'customer_id' => $customer->id, + 'order_date' => now(), + 'customer_name' => 'Test Customer', + 'customer_phone' => '1234567890', + 'customer_address' => 'Test Address', + 'status' => 'pending', + 'order_type' => 'direct', + 'total_amount' => 0, + ]); + + // 2. Prepare Payload + $items = []; + foreach ($variants as $variant) { + $items[] = [ + 'id' => $variant->id, + 'quantity' => 2, + 'selling_price' => 100, + ]; + } + + $payload = [ + 'order_type' => 'direct', + 'order_date' => now()->format('Y-m-d'), + 'customer' => [ + 'name' => 'Test Customer', + 'mobile' => '1234567890', + 'address' => 'Test Address', + 'city' => 'Test City', + ], + 'items' => $items, + 'payment_method' => 'cod', + 'call_status' => 'pending', + ]; + + // 3. Measure Queries + DB::flushQueryLog(); + DB::enableQueryLog(); + + $response = $this->actingAs($user)->putJson(route('orders.update', $order->id), $payload); + + $response->assertStatus(200); + + $queryLog = DB::getQueryLog(); + $queryCount = count($queryLog); + + + // Assert query count is significantly reduced (e.g. < 45) + // Baseline was 66. + $this->assertLessThan(45, $queryCount, "Query count should be optimized (was 66, expected < 45)"); + + // Assert stock decrement + foreach ($variants as $variant) { + $this->assertDatabaseHas('product_variants', [ + 'id' => $variant->id, + 'quantity' => 98, // 100 - 2 + ]); + } + } +}