ソースを参照

fix: purchase master

コミット
e01b8f0962

+ 32
- 6
app/Http/Controllers/PurchaseController.php ファイルの表示

11
 use App\Models\StockProduct;
11
 use App\Models\StockProduct;
12
 use App\Models\Supplier;
12
 use App\Models\Supplier;
13
 use App\Services\HelperService;
13
 use App\Services\HelperService;
14
-use App\Services\PurchaseService;
15
 use Illuminate\Database\QueryException;
14
 use Illuminate\Database\QueryException;
16
 use Illuminate\Support\Facades\DB;
15
 use Illuminate\Support\Facades\DB;
17
 use Inertia\Inertia;
16
 use Inertia\Inertia;
40
                     fn($purchase) => [
39
                     fn($purchase) => [
41
                         "id" => $purchase->id,
40
                         "id" => $purchase->id,
42
                         "updatedAt" => $purchase->updated_at,
41
                         "updatedAt" => $purchase->updated_at,
43
-                        "email" => $purchase->supplier->email,
44
                         "name" => $purchase->supplier->name,
42
                         "name" => $purchase->supplier->name,
45
                         "phone" => $purchase->supplier->phone,
43
                         "phone" => $purchase->supplier->phone,
44
+                        "email" => $purchase->supplier->email,
46
                         "price" => HelperService::setRupiahFormat(
45
                         "price" => HelperService::setRupiahFormat(
47
-                            PurchaseService::totalPrice($purchase)
46
+                            $purchase->purchaseDetail->sum("price")
48
                         ),
47
                         ),
49
                         "status" => $purchase->status,
48
                         "status" => $purchase->status,
50
                     ]
49
                     ]
74
             "historyProductPurchase" => Inertia::lazy(
73
             "historyProductPurchase" => Inertia::lazy(
75
                 fn() => PurchaseDetail::historyProductPurchase(
74
                 fn() => PurchaseDetail::historyProductPurchase(
76
                     request()->only("productNumber", "supplierId")
75
                     request()->only("productNumber", "supplierId")
77
-                )->first()
76
+                )
77
+                    ->orderBy("price", "desc")
78
+                    ->get()
79
+                    ->transform(
80
+                        fn($purchaseDetail) => [
81
+                            "id" => $purchaseDetail->id,
82
+                            "price" => $purchaseDetail->price,
83
+                            "qty" => $purchaseDetail->qty,
84
+                            "ppn" => $purchaseDetail->purchase->ppn,
85
+                        ]
86
+                    )
87
+                    ->first()
78
             ),
88
             ),
79
         ]);
89
         ]);
80
     }
90
     }
142
                     "id" => $purchase->id,
152
                     "id" => $purchase->id,
143
                     "number" => $purchase->product_number,
153
                     "number" => $purchase->product_number,
144
                     "name" => $purchase->product->name,
154
                     "name" => $purchase->product->name,
145
-                    "price" => $purchase->price,
155
+                    "price" => $purchase->getRawOriginal("price"),
146
                     "qty" => $purchase->qty,
156
                     "qty" => $purchase->qty,
147
                     "unit" => $purchase->product->unit,
157
                     "unit" => $purchase->product->unit,
148
                 ]
158
                 ]
174
                     "id" => $purchase->id,
184
                     "id" => $purchase->id,
175
                     "number" => $purchase->product_number,
185
                     "number" => $purchase->product_number,
176
                     "name" => $purchase->product->name,
186
                     "name" => $purchase->product->name,
177
-                    "price" => $purchase->price,
187
+                    "price" => $purchase->getRawOriginal("price"),
178
                     "qty" => $purchase->qty,
188
                     "qty" => $purchase->qty,
179
                     "unit" => $purchase->product->unit,
189
                     "unit" => $purchase->product->unit,
180
                 ]
190
                 ]
181
             ),
191
             ),
192
+            "historyProductPurchase" => Inertia::lazy(
193
+                fn() => PurchaseDetail::historyProductPurchase(
194
+                    request()->only("productNumber", "supplierId")
195
+                )
196
+                    ->orderBy("price", "desc")
197
+                    ->get()
198
+                    ->transform(
199
+                        fn($purchaseDetail) => [
200
+                            "id" => $purchaseDetail->id,
201
+                            "price" => $purchaseDetail->price,
202
+                            "qty" => $purchaseDetail->qty,
203
+                            "ppn" => $purchaseDetail->purchase->ppn,
204
+                        ]
205
+                    )
206
+                    ->first()
207
+            ),
182
         ]);
208
         ]);
183
     }
209
     }
184
 
210
 

+ 21
- 11
app/Models/PurchaseDetail.php ファイルの表示

2
 
2
 
3
 namespace App\Models;
3
 namespace App\Models;
4
 
4
 
5
-use Illuminate\Database\Eloquent\Factories\HasFactory;
5
+use App\Services\HelperService;
6
 use Illuminate\Database\Eloquent\Model;
6
 use Illuminate\Database\Eloquent\Model;
7
+use Illuminate\Database\Eloquent\Casts\Attribute;
8
+use Illuminate\Database\Eloquent\Factories\HasFactory;
7
 
9
 
8
 class PurchaseDetail extends Model
10
 class PurchaseDetail extends Model
9
 {
11
 {
11
 
13
 
12
     protected $fillable = ["price", "qty", "purchase_number", "product_number"];
14
     protected $fillable = ["price", "qty", "purchase_number", "product_number"];
13
 
15
 
16
+    protected function price(): Attribute
17
+    {
18
+        return Attribute::make(
19
+            get: function ($value) {
20
+                $ppn = Ppn::first()->ppn;
21
+
22
+                return $this->purchase->ppn
23
+                    ? HelperService::addPPN($value, $ppn)
24
+                    : $value;
25
+            }
26
+        );
27
+    }
28
+
14
     public function product()
29
     public function product()
15
     {
30
     {
16
         return $this->belongsTo(Product::class, "product_number", "number");
31
         return $this->belongsTo(Product::class, "product_number", "number");
17
     }
32
     }
18
 
33
 
19
-    public function supplier()
34
+    public function purchase()
20
     {
35
     {
21
-        return $this->hasOneThrough(
22
-            Supplier::class,
23
-            Purchase::class,
24
-            "number",
25
-            "id",
26
-            "purchase_number",
27
-            "supplier_id"
28
-        );
36
+        return $this->belongsTo(Purchase::class, "purchase_number", "number");
29
     }
37
     }
30
 
38
 
31
     public function scopeHistoryProductPurchase($query, array $filters)
39
     public function scopeHistoryProductPurchase($query, array $filters)
38
                 $query->whereRelation("product", "number", $search);
46
                 $query->whereRelation("product", "number", $search);
39
             })
47
             })
40
             ->when($filters["supplierId"] ?? null, function ($query, $search) {
48
             ->when($filters["supplierId"] ?? null, function ($query, $search) {
41
-                $query->whereHas("supplier");
49
+                $query->whereHas("purchase", function ($query) use ($search) {
50
+                    $query->where("supplier_id", $search);
51
+                });
42
             });
52
             });
43
     }
53
     }
44
 }
54
 }

+ 0
- 21
app/Services/PurchaseService.php ファイルの表示

1
-<?php
2
-namespace App\Services;
3
-
4
-use App\Models\Ppn;
5
-use App\Models\Purchase;
6
-
7
-class PurchaseService
8
-{
9
-    public static function totalPrice(Purchase $purchase)
10
-    {
11
-        return $purchase->purchaseDetail->sum(function ($purchaseDetail) use (
12
-            $purchase
13
-        ) {
14
-            $ppn = Ppn::first()->ppn;
15
-
16
-            return $purchase->ppn
17
-                ? HelperService::addPPN($purchaseDetail->price, $ppn)
18
-                : $purchaseDetail->price;
19
-        });
20
-    }
21
-}

+ 1
- 1
resources/js/pages/Purchases/Components/Details.vue ファイルの表示

77
       <div
77
       <div
78
         class="flex flex-column md:flex-row gap-2 md:gap-0 md:justify-content-between md:align-items-center"
78
         class="flex flex-column md:flex-row gap-2 md:gap-0 md:justify-content-between md:align-items-center"
79
       >
79
       >
80
-        <small>{{ message }}</small>
80
+        <span class="text-xs">{{ message }}</span>
81
 
81
 
82
         <Button
82
         <Button
83
           label="Simpan"
83
           label="Simpan"

+ 57
- 0
resources/js/pages/Purchases/Components/HistoryProduct.vue ファイルの表示

1
+<script setup>
2
+import { watch } from 'vue'
3
+import { Inertia } from '@inertiajs/inertia'
4
+import { usePage } from '@inertiajs/inertia-vue3'
5
+import AppInputNumber from '@/components/AppInputNumber.vue'
6
+import AppInputText from '@/components/AppInputText.vue'
7
+
8
+const props = defineProps(['product', 'supplier'])
9
+
10
+watch(
11
+  () => props.product,
12
+  () => {
13
+    if (props.product?.number && props.supplier?.id) {
14
+      Inertia.reload({
15
+        data: {
16
+          productNumber: props.product.number,
17
+          supplierId: props.supplier.id,
18
+        },
19
+        only: ['historyProductPurchase'],
20
+      })
21
+    }
22
+
23
+    usePage().props.value.historyProductPurchase = {}
24
+  }
25
+)
26
+</script>
27
+
28
+<template>
29
+  <template v-if="$page.props.historyProductPurchase?.id">
30
+    <div class="col-12">
31
+      <h3 class="text-lg">Riwayat Produk Sebelumnya</h3>
32
+    </div>
33
+    <div class="col-12 md:col-6">
34
+      <AppInputNumber
35
+        disabled
36
+        class="mb-0"
37
+        label="Harga"
38
+        placeholder="harga"
39
+        v-model="$page.props.historyProductPurchase.price"
40
+      />
41
+
42
+      <span v-if="$page.props.historyProductPurchase.ppn" class="text-xs">
43
+        Harga sudah termasuk PPN {{ $page.props.ppn }} %
44
+      </span>
45
+    </div>
46
+
47
+    <div class="col-12 md:col-6">
48
+      <AppInputText
49
+        disabled
50
+        label="Kuantitas"
51
+        placeholder="kuantitas"
52
+        type="number"
53
+        v-model="$page.props.historyProductPurchase.qty"
54
+      />
55
+    </div>
56
+  </template>
57
+</template>

+ 6
- 29
resources/js/pages/Purchases/Create.vue ファイルの表示

1
 <script setup>
1
 <script setup>
2
-import { watch, computed } from 'vue'
3
-import { Inertia } from '@inertiajs/inertia'
2
+import { computed } from 'vue'
4
 import { optionStatus } from './config'
3
 import { optionStatus } from './config'
5
 import { cartTable } from './config'
4
 import { cartTable } from './config'
6
 import Details from './Components/Details.vue'
5
 import Details from './Components/Details.vue'
7
 import Cart from './Components/Cart.vue'
6
 import Cart from './Components/Cart.vue'
7
+import HistoryProduct from './Components/HistoryProduct.vue'
8
 import { useProductCart } from './Composables/useProductCart'
8
 import { useProductCart } from './Composables/useProductCart'
9
 import { onShowDialog } from './Composables/onShowDialog'
9
 import { onShowDialog } from './Composables/onShowDialog'
10
 import { useForm } from '@/composables/useForm'
10
 import { useForm } from '@/composables/useForm'
60
   return optionStatus.filter((val) => val.value != 'success')
60
   return optionStatus.filter((val) => val.value != 'success')
61
 })
61
 })
62
 
62
 
63
-watch(
64
-  () => form.product,
65
-  () => {
66
-    if (form.product.id) {
67
-      Inertia.reload({
68
-        data: {
69
-          productNumber: form.product.number,
70
-          supplierId: form.supplier.id,
71
-        },
72
-        only: ['historyProductPurchase'],
73
-      })
74
-    }
75
-  }
76
-)
77
-
78
-const historyProductPrice = computed(() => {
79
-  return props.historyProductPurchase?.price
80
-})
81
-
82
 const {
63
 const {
83
   productCart,
64
   productCart,
84
   onClearProductCart,
65
   onClearProductCart,
196
                     />
177
                     />
197
                   </div>
178
                   </div>
198
 
179
 
199
-                  <div class="col-12 md:col-6">
200
-                    <AppInputNumber
201
-                      disabled
202
-                      label="Harga Sebelumya"
203
-                      placeholder="harga sebelumnya"
204
-                      v-model="historyProductPrice"
205
-                    />
206
-                  </div>
180
+                  <HistoryProduct
181
+                    :product="form.product"
182
+                    :supplier="form.supplier"
183
+                  />
207
 
184
 
208
                   <Divider type="dashed" />
185
                   <Divider type="dashed" />
209
 
186
 

+ 9
- 0
resources/js/pages/Purchases/Edit.vue ファイルの表示

3
 import { cartTable } from './config'
3
 import { cartTable } from './config'
4
 import Details from './Components/Details.vue'
4
 import Details from './Components/Details.vue'
5
 import Cart from './Components/Cart.vue'
5
 import Cart from './Components/Cart.vue'
6
+import HistoryProduct from './Components/HistoryProduct.vue'
6
 import { useProductCart } from './Composables/useProductCart'
7
 import { useProductCart } from './Composables/useProductCart'
7
 import { onShowDialog } from './Composables/onShowDialog'
8
 import { onShowDialog } from './Composables/onShowDialog'
8
 import { useForm } from '@/composables/useForm'
9
 import { useForm } from '@/composables/useForm'
24
     default: [],
25
     default: [],
25
   },
26
   },
26
   purchaseDetail: Array,
27
   purchaseDetail: Array,
28
+  historyProductPurchase: Object,
27
 })
29
 })
28
 
30
 
29
 const form = useForm({
31
 const form = useForm({
143
                     />
145
                     />
144
                   </div>
146
                   </div>
145
 
147
 
148
+                  <HistoryProduct
149
+                    :product="form.product"
150
+                    :supplier="form.supplier"
151
+                  />
152
+
153
+                  <Divider type="dashed" />
154
+
146
                   <div class="col-12 md:col-6">
155
                   <div class="col-12 md:col-6">
147
                     <AppInputNumber
156
                     <AppInputNumber
148
                       :disabled="!form.supplier?.id"
157
                       :disabled="!form.supplier?.id"

+ 1
- 1
resources/js/pages/Sales/Components/Details.vue ファイルの表示

77
       <div
77
       <div
78
         class="flex flex-column md:flex-row gap-2 md:gap-0 md:justify-content-between md:align-items-center"
78
         class="flex flex-column md:flex-row gap-2 md:gap-0 md:justify-content-between md:align-items-center"
79
       >
79
       >
80
-        <small>{{ message }}</small>
80
+        <span class="text-xs">{{ message }}</span>
81
 
81
 
82
         <Button
82
         <Button
83
           label="Simpan"
83
           label="Simpan"