浏览代码

Fix handed over MAF sum calculation in reports

Alexander Musikhin 3 天之前
父节点
当前提交
88c48a6d99

+ 28 - 28
app/Http/Controllers/ReportController.php

@@ -29,6 +29,7 @@ class ReportController extends Controller
     {
         $mountStatuses = [5, 7, 8, 9, 10];
         $doneStatuses = [9, 10];
+        $handedOverStatus = Order::STATUS_HANDED_OVER;
         $objectTypes = ObjectType::query()->get()->pluck('name', 'id')->toArray();
         $this->data['objectTypes'] = $objectTypes;
         $user_ids = Order::query()->distinct()->get('user_id')->pluck('user_id')->toArray();
@@ -53,15 +54,9 @@ class ReportController extends Controller
             $query->whereIn('order_status_id', $mountStatuses);
         })->count();
 
-        // общая сумма mount
-        $this->data['totalMountSum'] = Price::format(
-            ProductSKU::query()->
-            whereHas('order', function ($query) use ($mountStatuses) {
-                $query->whereIn('order_status_id', $mountStatuses);
-            })
-            ->withSum('product', 'total_price')
-            ->get()
-            ->sum('product_sum_total_price')
+        // сумма сданных МАФ по площадкам со статусом "Сдана"
+        $this->data['totalHandedOverSum'] = Price::format(
+            $this->getDoneSumByStatus($handedOverStatus)
         );
 
         // done by managers
@@ -184,13 +179,7 @@ class ReportController extends Controller
         );
         // общая сумма done
         $this->data['totalDoneSum'] = Price::format(
-            ProductSKU::query()->
-            whereHas('order', function ($query) use ($doneStatuses) {
-                $query->whereIn('order_status_id', $doneStatuses);
-            })
-                ->withSum('product', 'total_price')
-                ->get()
-                ->sum('product_sum_total_price') / 100
+            $this->getDoneSumByStatus($handedOverStatus)
         );
 
         $districts = District::query()->get()->pluck('shortname', 'id')->toArray();
@@ -234,7 +223,7 @@ class ReportController extends Controller
             $this->data['byDistrict'][$district] = [
                 'name'  => $district,
                 'totalSum' => $this->getDistrictSum($districtId),
-                'doneSum' => $this->getDistrictSum($districtId, $doneStatuses),
+                'doneSum' => $this->getDistrictSum($districtId, [$handedOverStatus]),
                 'totalOrders' => $totalOrders,
                 'totalMafs' => $totalMafs,
                 'readyOrders' => $readyOrders,
@@ -331,19 +320,30 @@ class ReportController extends Controller
     private function getDistrictSum($districtId, $done = false)
     {
         return Price::format(
-            ProductSKU::query()->
-            whereHas('order', function ($query) use ($done, $districtId) {
-                $query->where('district_id', $districtId);
-                if($done){
-                    $query->whereIn('order_status_id', $done);
-                }
-            })
-            ->withSum('product', 'total_price')
-            ->get()
-            ->sum('product_sum_total_price') / 100
+            $this->getDoneSumByStatus($done ?: null, $districtId)
         );
 
-}
+    }
+
+    private function getDoneSumByStatus(array|int|null $statuses = null, ?int $districtId = null): float
+    {
+        $query = ProductSKU::query()
+            ->join('orders', 'orders.id', '=', 'products_sku.order_id')
+            ->join('products', 'products.id', '=', 'products_sku.product_id')
+            ->where('orders.year', year())
+            ->where('products.year', year());
+
+        if ($districtId !== null) {
+            $query->where('orders.district_id', $districtId);
+        }
+
+        if ($statuses !== null && $statuses !== false) {
+            $statuses = is_array($statuses) ? $statuses : [$statuses];
+            $query->whereIn('orders.order_status_id', $statuses);
+        }
+
+        return ((float) $query->sum('products.total_price')) / 100;
+    }
 
 
 }

+ 1 - 1
resources/views/reports/index.blade.php

@@ -125,7 +125,7 @@
                 </div>
                 <div class="col-xl-4">
                     <div class="text-center text-success fs-4 fw-bold">
-                        {!! $totalMountSum !!}
+                        {!! $totalHandedOverSum !!}
                     </div>
                     <div class="text-center">
                         Сдано на сумму

+ 54 - 0
tests/Feature/ReportControllerTest.php

@@ -2,7 +2,10 @@
 
 namespace Tests\Feature;
 
+use App\Helpers\Price;
 use App\Models\Order;
+use App\Models\Product;
+use App\Models\ProductSKU;
 use App\Models\Reclamation;
 use App\Models\ReclamationDetail;
 use App\Models\Role;
@@ -128,4 +131,55 @@ class ReportControllerTest extends TestCase
         $response->assertViewHas('totalSum');
         $response->assertViewHas('totalDoneSum');
     }
+
+    public function test_reports_index_counts_done_sum_only_for_handed_over_sites(): void
+    {
+        $handedOverOrder = Order::factory()->create([
+            'user_id' => $this->adminUser->id,
+            'order_status_id' => Order::STATUS_HANDED_OVER,
+        ]);
+        $handedOverProduct = Product::factory()->create([
+            'total_price' => 1000,
+        ]);
+        ProductSKU::factory()
+            ->forOrder($handedOverOrder)
+            ->forProduct($handedOverProduct)
+            ->create();
+
+        $inMountOrder = Order::factory()->create([
+            'user_id' => $this->adminUser->id,
+            'order_status_id' => Order::STATUS_IN_MOUNT,
+        ]);
+        $inMountProduct = Product::factory()->create([
+            'total_price' => 2000,
+        ]);
+        ProductSKU::factory()
+            ->forOrder($inMountOrder)
+            ->forProduct($inMountProduct)
+            ->create();
+
+        $handedOverWithNotesOrder = Order::factory()->create([
+            'user_id' => $this->adminUser->id,
+            'order_status_id' => Order::STATUS_HANDED_OVER_WITH_NOTES,
+        ]);
+        $handedOverWithNotesProduct = Product::factory()->create([
+            'total_price' => 3000,
+        ]);
+        ProductSKU::factory()
+            ->forOrder($handedOverWithNotesOrder)
+            ->forProduct($handedOverWithNotesProduct)
+            ->create();
+
+        $response = $this->actingAs($this->adminUser)->get(route('reports.index'));
+
+        $expectedSum = Price::format(1000);
+
+        $response->assertViewHas('totalHandedOverSum', $expectedSum);
+        $response->assertViewHas('totalDoneSum', $expectedSum);
+        $response->assertViewHas('byDistrict', function (array $byDistrict) use ($handedOverOrder, $expectedSum) {
+            $districtName = $handedOverOrder->district->shortname;
+
+            return ($byDistrict[$districtName]['doneSum'] ?? null) === $expectedSum;
+        });
+    }
 }