Selaa lähdekoodia

feat: customer history purchase report

Muhammad Iqbal Afandi 3 vuotta sitten
vanhempi
commit
dc20e5bf4d

+ 72
- 0
app/Exports/CustomerHistoryExport.php Näytä tiedosto

@@ -0,0 +1,72 @@
1
+<?php
2
+
3
+namespace App\Exports;
4
+
5
+use Illuminate\Contracts\View\View;
6
+use Maatwebsite\Excel\Concerns\FromView;
7
+use Maatwebsite\Excel\Concerns\Exportable;
8
+use Maatwebsite\Excel\Concerns\WithStyles;
9
+use Illuminate\Contracts\Support\Responsable;
10
+use Maatwebsite\Excel\Concerns\ShouldAutoSize;
11
+use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
12
+use Maatwebsite\Excel\Concerns\WithPreCalculateFormulas;
13
+
14
+class CustomerHistoryExport implements
15
+    FromView,
16
+    Responsable,
17
+    WithStyles,
18
+    ShouldAutoSize,
19
+    WithPreCalculateFormulas
20
+{
21
+    use Exportable;
22
+
23
+    private $fileName = "customer-history-report.xlsx";
24
+
25
+    public function __construct(private array $data)
26
+    {
27
+    }
28
+
29
+    public function view(): View
30
+    {
31
+        ["sales" => $sales] = $this->data;
32
+
33
+        return view("Excel.Customers.Export", compact("sales"));
34
+    }
35
+
36
+    public function styles(Worksheet $sheet)
37
+    {
38
+        $lastRow = $sheet->getHighestDataRow();
39
+
40
+        $lastContent = $lastRow - 1;
41
+
42
+        $sheet->setCellValue("H$lastRow", "=SUM(H5:H$lastContent)");
43
+
44
+        $sheet
45
+            ->getStyle("H")
46
+            ->getNumberFormat()
47
+            ->setFormatCode("#,###");
48
+
49
+        return [
50
+            1 => [
51
+                "font" => ["bold" => true, "size" => 12],
52
+                "alignment" => [
53
+                    "vertical" => "center",
54
+                    "horizontal" => "center",
55
+                ],
56
+            ],
57
+            2 => [
58
+                "font" => ["bold" => true, "size" => 12],
59
+                "alignment" => [
60
+                    "vertical" => "center",
61
+                    "horizontal" => "center",
62
+                ],
63
+            ],
64
+            4 => [
65
+                "font" => ["bold" => true],
66
+            ],
67
+            $lastRow => [
68
+                "font" => ["bold" => true, "size" => 12],
69
+            ],
70
+        ];
71
+    }
72
+}

+ 35
- 1
app/Http/Controllers/CustomerController.php Näytä tiedosto

@@ -3,6 +3,8 @@
3 3
 namespace App\Http\Controllers;
4 4
 
5 5
 use App\Models\Customer;
6
+use App\Models\SaleDetail;
7
+use App\Exports\CustomerHistoryExport;
6 8
 use App\Http\Requests\Customer\StoreCustomerRequest;
7 9
 use App\Http\Requests\Customer\UpdateCustomerRequest;
8 10
 
@@ -71,11 +73,19 @@ class CustomerController extends Controller
71 73
     public function show(Customer $customer)
72 74
     {
73 75
         return inertia("Customers/Show", [
76
+            "initialFilters" => request()->only(
77
+                "start_date",
78
+                "end_date",
79
+                "number_product"
80
+            ),
74 81
             "customer" => $customer,
75 82
             "historyPurchase" => $customer
76 83
                 ->sales()
84
+                ->filter(
85
+                    request()->only("start_date", "end_date", "product_number")
86
+                )
77 87
                 ->latest()
78
-                ->paginate(10)
88
+                ->paginate(1)
79 89
                 ->withQueryString()
80 90
                 ->through(
81 91
                     fn($sale) => [
@@ -126,4 +136,28 @@ class CustomerController extends Controller
126 136
 
127 137
         return back()->with("success", __("messages.success.destroy.customer"));
128 138
     }
139
+
140
+    public function historyPurchaseExcel()
141
+    {
142
+        $this->authorize("viewAny", Customer::class);
143
+
144
+        return new CustomerHistoryExport([
145
+            "sales" => SaleDetail::filter(
146
+                request()->only("start_date", "end_date", "product_number")
147
+            )
148
+                ->latest()
149
+                ->get()
150
+                ->map(
151
+                    fn($saleDetail) => [
152
+                        "createdAt" => $saleDetail->created_at,
153
+                        "name" => $saleDetail->product->name,
154
+                        "number" => $saleDetail->sale->number,
155
+                        "qty" => $saleDetail->qty,
156
+                        "status" => $saleDetail->sale->status,
157
+                        "ppn" => $saleDetail->sale->ppn,
158
+                        "price" => $saleDetail->price * $saleDetail->qty,
159
+                    ]
160
+                ),
161
+        ]);
162
+    }
129 163
 }

+ 17
- 0
app/Models/Sale.php Näytä tiedosto

@@ -48,4 +48,21 @@ class Sale extends Model
48 48
                 });
49 49
         });
50 50
     }
51
+
52
+    public function scopeFilter($query, array $filters)
53
+    {
54
+        $query
55
+            ->when($filters["start_date"] ?? null, function ($query, $search) {
56
+                $query->whereDate("created_at", ">=", $search);
57
+            })
58
+            ->when($filters["end_date"] ?? null, function ($query, $search) {
59
+                $query->whereDate("created_at", "<=", $search);
60
+            })
61
+            ->when($filters["product_number"] ?? null, function (
62
+                $query,
63
+                $search
64
+            ) {
65
+                $query->where("number", "like", "%" . $search . "%");
66
+            });
67
+    }
51 68
 }

+ 8
- 0
app/Models/SaleDetail.php Näytä tiedosto

@@ -70,6 +70,14 @@ class SaleDetail extends Model
70 70
             })
71 71
             ->when($filters["end_date"] ?? null, function ($query, $search) {
72 72
                 $query->whereDate("created_at", "<=", $search);
73
+            })
74
+            ->when($filters["product_number"] ?? null, function (
75
+                $query,
76
+                $search
77
+            ) {
78
+                $query->whereHas("sale", function ($query) use ($search) {
79
+                    $query->where("number", "like", "%" . $search . "%");
80
+                });
73 81
             });
74 82
     }
75 83
 }

+ 3
- 0
lang/en/words.php Näytä tiedosto

@@ -50,4 +50,7 @@ return [
50 50
     "total_price" => "Total Price",
51 51
     "status" => "Status",
52 52
     "quantity" => "Quantity",
53
+    "number" => "Number",
54
+    "product_name" => "Product Name",
55
+    "report_history_purchase" => "Report History Purchase",
53 56
 ];

+ 3
- 0
lang/id/words.php Näytä tiedosto

@@ -50,4 +50,7 @@ return [
50 50
     "total_price" => "Total Harga",
51 51
     "status" => "Status",
52 52
     "quantity" => "Kuantitas",
53
+    "number" => "Nomor",
54
+    "name_product" => "Nama Produk",
55
+    "report_history_purchase" => "Laporan History Pembelian",
53 56
 ];

+ 54
- 2
resources/js/pages/Customers/Show.vue Näytä tiedosto

@@ -1,12 +1,28 @@
1 1
 <script setup>
2 2
 import { detailTable } from './config'
3
+import AppPagination from '@/components/AppPagination.vue'
4
+import AppDateRangeFilter from '@/components/AppDateRangeFilter.vue'
5
+import AppSearchFilter from '@/components/AppSearchFilter.vue'
3 6
 import AppButtonLink from '@/components/AppButtonLink.vue'
7
+import AppResetFilter from '@/components/AppResetFilter.vue'
4 8
 import DashboardLayout from '@/layouts/Dashboard/DashboardLayout.vue'
5 9
 
6 10
 defineProps({
11
+  initialFilters: Object,
7 12
   customer: Object,
8
-  historyPurchase: Object,
13
+  historyPurchase: {
14
+    type: Object,
15
+    default: {
16
+      data: [],
17
+      links: [],
18
+      total: 0,
19
+    },
20
+  },
9 21
 })
22
+
23
+const exportExcel = () => {
24
+  return '/customers/history-purchase/excel' + location.search
25
+}
10 26
 </script>
11 27
 
12 28
 <template>
@@ -51,8 +67,42 @@ defineProps({
51 67
           :value="historyPurchase.data"
52 68
           :rowHover="true"
53 69
           :stripedRows="true"
54
-          @row-click="detail($event.data)"
55 70
         >
71
+          <template #header>
72
+            <div class="grid">
73
+              <div class="col-12 sm:col-6 lg:col-4">
74
+                <AppDateRangeFilter
75
+                  placeholder="filter waktu..."
76
+                  :name-param="['start_date', 'end_date']"
77
+                  :initial-date-rage="initialFilters"
78
+                />
79
+              </div>
80
+
81
+              <div class="col-12 sm:col-6 lg:col-4">
82
+                <AppSearchFilter
83
+                  placeholder="Nomor Produk"
84
+                  name-param="product_number"
85
+                  :initial-search="initialFilters"
86
+                />
87
+              </div>
88
+
89
+              <div class="col-12 sm:col-6 lg:col-4">
90
+                <AppResetFilter :url="route('customers.show', customer.id)" />
91
+              </div>
92
+
93
+              <div class="col-12">
94
+                <AppButtonLink
95
+                  v-if="historyPurchase.total"
96
+                  label="Export excel"
97
+                  class-button="p-button-outlined md:w-16rem"
98
+                  icon="pi pi-file-excel"
99
+                  :inertia-link="false"
100
+                  :href="exportExcel()"
101
+                />
102
+              </div>
103
+            </div>
104
+          </template>
105
+
56 106
           <Column
57 107
             v-for="value in detailTable"
58 108
             :key="value.field"
@@ -73,5 +123,7 @@ defineProps({
73 123
         </DataTable>
74 124
       </div>
75 125
     </div>
126
+
127
+    <AppPagination :links="historyPurchase.links" />
76 128
   </DashboardLayout>
77 129
 </template>

+ 41
- 0
resources/views/Excel/Customers/Export.blade.php Näytä tiedosto

@@ -0,0 +1,41 @@
1
+<table>
2
+    <thead>
3
+        <tr>
4
+            <th colspan="8">{{ __('words.report_history_purchase') }}</th>
5
+        </tr>
6
+        <tr>
7
+            <th colspan="8" rowspan="2">{{ __('words.period', ['number' => '']) }}
8
+                {{ $sales->first()['createdAt'] }}
9
+                -
10
+                {{ $sales->last()['createdAt'] }} </th>
11
+        </tr>
12
+        <tr></tr>
13
+        <tr>
14
+            <th>#</th>
15
+            <th>{{ __('words.date') }}</th>
16
+            <th>{{ __('words.number') }}</th>
17
+            <th>{{ __('words.name_product') }}</th>
18
+            <th>{{ __('words.quantity') }}</th>
19
+            <th>{{ __('words.status') }}</th>
20
+            <th>PPN</th>
21
+            <th>{{ __('words.total_price') }}</th>
22
+        </tr>
23
+    </thead>
24
+    <tbody>
25
+        @foreach ($sales as $index => $sale)
26
+            <tr>
27
+                <td>{{ ++$index }}</td>
28
+                <td>{{ $sale['createdAt'] }}</td>
29
+                <td>{{ $sale['number'] }}</td>
30
+                <td>{{ $sale['name'] }}</td>
31
+                <td>{{ $sale['qty'] }}</td>
32
+                <td>{{ $sale['status'] }}</td>
33
+                <td>{{ $sale['ppn'] }}</td>
34
+                <td>{{ $sale['price'] }}</td>
35
+            </tr>
36
+        @endforeach
37
+        <tr>
38
+            <td colspan="7">{{ __('words.total') }}</td>
39
+        </tr>
40
+    </tbody>
41
+</table>

+ 5
- 0
routes/web.php Näytä tiedosto

@@ -52,6 +52,11 @@ Route::middleware(["auth", "verified", "checkBlocked"])->group(function () {
52 52
 
53 53
     Route::resource("/settings", SettingController::class);
54 54
 
55
+    Route::get("/customers/history-purchase/excel", [
56
+        CustomerController::class,
57
+        "historyPurchaseExcel",
58
+    ])->name("customers.history-purchase.excel");
59
+
55 60
     Route::resource("/customers", CustomerController::class);
56 61
 
57 62
     Route::get("/purchases/pdf/invoice/{purchase}", [