Browse Source

fix: report master

Muhammad Iqbal Afandi 3 years ago
parent
commit
c505589af9

+ 72
- 0
app/Exports/SaleDetailsExport.php View File

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 SaleDetailsExport implements
15
+    FromView,
16
+    Responsable,
17
+    WithStyles,
18
+    ShouldAutoSize,
19
+    WithPreCalculateFormulas
20
+{
21
+    use Exportable;
22
+
23
+    private $fileName = "sale-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.Sales.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("E$lastRow", "=SUM(E5:E$lastContent)");
43
+
44
+        $sheet
45
+            ->getStyle("E")
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
+}

+ 19
- 25
app/Http/Controllers/SalesController.php View File

2
 
2
 
3
 namespace App\Http\Controllers;
3
 namespace App\Http\Controllers;
4
 
4
 
5
+use App\Exports\SaleDetailsExport;
5
 use App\Models\Ppn;
6
 use App\Models\Ppn;
6
 use App\Models\Sale;
7
 use App\Models\Sale;
7
 use Inertia\Inertia;
8
 use Inertia\Inertia;
231
     public function report()
232
     public function report()
232
     {
233
     {
233
         return inertia("Sales/Report", [
234
         return inertia("Sales/Report", [
234
-            "params" => [
235
-                "filters" => request()->only("start_date", "end_date"),
236
-            ],
235
+            "filters" => request()->only("start_date", "end_date"),
237
             "sales" => Inertia::lazy(
236
             "sales" => Inertia::lazy(
238
                 fn() => SaleDetail::filter(
237
                 fn() => SaleDetail::filter(
239
                     request()->only("start_date", "end_date")
238
                     request()->only("start_date", "end_date")
240
                 )
239
                 )
241
                     ->latest()
240
                     ->latest()
242
-                    ->paginate(10)
241
+                    ->paginate(3)
243
                     ->withQueryString()
242
                     ->withQueryString()
244
                     ->through(
243
                     ->through(
245
                         fn($saleDetail) => [
244
                         fn($saleDetail) => [
246
-                            "updatedAt" => $saleDetail->updated_at,
245
+                            "createdAt" => $saleDetail->created_at,
247
                             "totalPrice" => FunctionService::rupiahFormat(
246
                             "totalPrice" => FunctionService::rupiahFormat(
248
                                 $saleDetail->price * $saleDetail->qty
247
                                 $saleDetail->price * $saleDetail->qty
249
                             ),
248
                             ),
251
                         ]
250
                         ]
252
                     )
251
                     )
253
             ),
252
             ),
254
-            // "data" => [
255
-            //     "sales" => Inertia::lazy(
256
-            //         fn() => SaleDetail::filter(
257
-            //             request()->only("start_date", "end_date")
258
-            //         )
259
-            //             ->latest()
260
-            //             ->paginate(10)
261
-            //             ->withQueryString()
262
-            //             ->through(
263
-            //                 fn($saleDetail) => [
264
-            //                     "updatedAt" => $saleDetail->updated_at,
265
-            //                     "totalPrice" => FunctionService::rupiahFormat(
266
-            //                         $saleDetail->price * $saleDetail->qty
267
-            //                     ),
268
-            //                     "status" => $saleDetail->sale->status,
269
-            //                 ]
270
-            //             )
271
-            //     ),
272
-            // ],
273
         ]);
253
         ]);
274
     }
254
     }
275
 
255
 
276
     public function reportExcel()
256
     public function reportExcel()
277
     {
257
     {
278
-        //
258
+        return new SaleDetailsExport([
259
+            "sales" => SaleDetail::filter(
260
+                request()->only("start_date", "end_date")
261
+            )
262
+                ->latest()
263
+                ->get()
264
+                ->map(
265
+                    fn($saleDetail) => [
266
+                        "createdAt" => $saleDetail->created_at,
267
+                        "qty" => $saleDetail->qty,
268
+                        "status" => $saleDetail->sale->status,
269
+                        "price" => $saleDetail->price * $saleDetail->qty,
270
+                    ]
271
+                ),
272
+        ]);
279
     }
273
     }
280
 }
274
 }

+ 1
- 1
app/Http/Controllers/SupplierController.php View File

22
     {
22
     {
23
         return inertia("Suppliers/Index", [
23
         return inertia("Suppliers/Index", [
24
             "initialSearch" => request("search"),
24
             "initialSearch" => request("search"),
25
-            "suppliers" => Supplier::filter(request()->only("search"))
25
+            "suppliers" => Supplier::search(request()->only("search"))
26
                 ->latest()
26
                 ->latest()
27
                 ->paginate(10)
27
                 ->paginate(10)
28
                 ->withQueryString()
28
                 ->withQueryString()

+ 1
- 1
app/Models/SaleDetail.php View File

14
 
14
 
15
     protected $fillable = ["price", "qty", "sale_number", "product_number"];
15
     protected $fillable = ["price", "qty", "sale_number", "product_number"];
16
 
16
 
17
-    protected function updatedAt(): Attribute
17
+    protected function createdAt(): Attribute
18
     {
18
     {
19
         return Attribute::make(
19
         return Attribute::make(
20
             get: fn($value) => Carbon::parse($value)->translatedFormat(
20
             get: fn($value) => Carbon::parse($value)->translatedFormat(

+ 6
- 0
lang/en/words.php View File

44
     "best_product" => "Best Product",
44
     "best_product" => "Best Product",
45
     "sale_and_purchase" => "Sale and Purchase",
45
     "sale_and_purchase" => "Sale and Purchase",
46
     "period" => "Period :number",
46
     "period" => "Period :number",
47
+    "report_sale" => "Sale Report",
48
+    "report_purchase" => "Purchase Report",
49
+    "date" => "Date",
50
+    "total_price" => "Total Price",
51
+    "status" => "Status",
52
+    "quantity" => "Quantity",
47
 ];
53
 ];

+ 6
- 0
lang/id/words.php View File

44
     "best_product" => "Produk Terlaris",
44
     "best_product" => "Produk Terlaris",
45
     "sale_and_purchase" => "Penjualan dan Pembelian",
45
     "sale_and_purchase" => "Penjualan dan Pembelian",
46
     "period" => "Periode :number",
46
     "period" => "Periode :number",
47
+    "report_sale" => "Laporan Penjualan",
48
+    "report_purchase" => "Laporan Pembelian",
49
+    "date" => "Tanggal",
50
+    "total_price" => "Total Harga",
51
+    "status" => "Status",
52
+    "quantity" => "Kuantitas",
47
 ];
53
 ];

+ 9
- 2
resources/js/components/AppFilterDateRange.vue View File

45
       filters.startDate = dayjs(filters.dates[0]).format('YYYY-MM-DD')
45
       filters.startDate = dayjs(filters.dates[0]).format('YYYY-MM-DD')
46
 
46
 
47
       filters.endDate = null
47
       filters.endDate = null
48
-
49
-      removeParams('end_date')
50
     }
48
     }
51
 
49
 
52
     Inertia.reload({
50
     Inertia.reload({
66
 
64
 
67
   window.history.replaceState({}, '', `${location.pathname}?${urlParams}`)
65
   window.history.replaceState({}, '', `${location.pathname}?${urlParams}`)
68
 }
66
 }
67
+
68
+const dateSelect = () => {
69
+  if (filters.dates[0]) {
70
+    removeParams('end_date')
71
+  }
72
+
73
+  removeParams('page')
74
+}
69
 </script>
75
 </script>
70
 
76
 
71
 <template>
77
 <template>
74
     selection-mode="range"
80
     selection-mode="range"
75
     date-format="dd/mm/yy"
81
     date-format="dd/mm/yy"
76
     :manual-input="false"
82
     :manual-input="false"
83
+    @date-select="dateSelect"
77
     v-model="filters.dates"
84
     v-model="filters.dates"
78
   />
85
   />
79
 </template>
86
 </template>

+ 30
- 3
resources/js/pages/Sales/Report.vue View File

1
 <script setup>
1
 <script setup>
2
 import { reportTable } from './config'
2
 import { reportTable } from './config'
3
 import AppFilterDateRange from '@/components/AppFilterDateRange.vue'
3
 import AppFilterDateRange from '@/components/AppFilterDateRange.vue'
4
+import AppButtonLink from '@/components/AppButtonLink.vue'
5
+import AppPagination from '@/components/AppPagination.vue'
4
 import DashboardLayout from '@/layouts/Dashboard/DashboardLayout.vue'
6
 import DashboardLayout from '@/layouts/Dashboard/DashboardLayout.vue'
5
 
7
 
6
 defineProps({
8
 defineProps({
7
-  params: Object,
8
-  sales: Object,
9
+  filters: Object,
10
+  sales: {
11
+    type: Object,
12
+    default: {
13
+      data: [],
14
+      links: [],
15
+      total: 0,
16
+    },
17
+  },
9
 })
18
 })
19
+
20
+const exportExcel = () => {
21
+  return `/sales/excel/report${location.search}`
22
+}
10
 </script>
23
 </script>
11
 
24
 
12
 <template>
25
 <template>
14
     <DataTable
27
     <DataTable
15
       responsive-layout="scroll"
28
       responsive-layout="scroll"
16
       column-resize-mode="expand"
29
       column-resize-mode="expand"
30
+      :value="sales.data"
17
       :rowHover="true"
31
       :rowHover="true"
18
       :stripedRows="true"
32
       :stripedRows="true"
19
     >
33
     >
25
             <AppFilterDateRange
39
             <AppFilterDateRange
26
               placeholder="filter waktu..."
40
               placeholder="filter waktu..."
27
               refresh-data="sales"
41
               refresh-data="sales"
28
-              :initial-filter="params.filters"
42
+              :initial-filter="filters"
43
+            />
44
+          </div>
45
+
46
+          <div class="col-12">
47
+            <AppButtonLink
48
+              v-if="sales.total"
49
+              label="Export excel"
50
+              class-button="p-button-outlined md:w-16rem"
51
+              icon="pi pi-file-excel"
52
+              :inertia-link="false"
53
+              :href="exportExcel()"
29
             />
54
             />
30
           </div>
55
           </div>
31
         </div>
56
         </div>
38
         :key="value.field"
63
         :key="value.field"
39
       />
64
       />
40
     </DataTable>
65
     </DataTable>
66
+
67
+    <AppPagination :links="sales.links" />
41
   </DashboardLayout>
68
   </DashboardLayout>
42
 </template>
69
 </template>

+ 1
- 1
resources/js/pages/Sales/config.js View File

26
 ]
26
 ]
27
 
27
 
28
 export const reportTable = [
28
 export const reportTable = [
29
-  { field: 'updatedAt', header: 'Tanggal' },
29
+  { field: 'createdAt', header: 'Tanggal' },
30
   { field: 'totalPrice', header: 'Total Harga' },
30
   { field: 'totalPrice', header: 'Total Harga' },
31
   { field: 'status', header: 'Status' },
31
   { field: 'status', header: 'Status' },
32
 ]
32
 ]

+ 35
- 0
resources/views/Excel/Sales/Export.blade.php View File

1
+<table>
2
+    <thead>
3
+        <tr>
4
+            <th colspan="5">{{ __('words.report_sale') }}</th>
5
+        </tr>
6
+        <tr>
7
+            <th colspan="5" 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.quantity') }}</th>
17
+            <th>{{ __('words.status') }}</th>
18
+            <th>{{ __('words.total_price') }}</th>
19
+        </tr>
20
+    </thead>
21
+    <tbody>
22
+        @foreach ($sales as $index => $sale)
23
+            <tr>
24
+                <td>{{ ++$index }}</td>
25
+                <td>{{ $sale['createdAt'] }}</td>
26
+                <td>{{ $sale['qty'] }}</td>
27
+                <td>{{ $sale['status'] }}</td>
28
+                <td>{{ $sale['price'] }}</td>
29
+            </tr>
30
+        @endforeach
31
+        <tr>
32
+            <td colspan="4">Total</td>
33
+        </tr>
34
+    </tbody>
35
+</table>

+ 2
- 5
routes/web.php View File

67
     Route::get("/purchases/excel/report", [
67
     Route::get("/purchases/excel/report", [
68
         PurchaseController::class,
68
         PurchaseController::class,
69
         "reportExcel",
69
         "reportExcel",
70
-    ])->name("purchases.excel.report");
70
+    ]);
71
 
71
 
72
     Route::get("/purchases/report", [PurchaseController::class, "report"]);
72
     Route::get("/purchases/report", [PurchaseController::class, "report"]);
73
 
73
 
83
         "deliveryOrder",
83
         "deliveryOrder",
84
     ])->name("sales.pdf.do");
84
     ])->name("sales.pdf.do");
85
 
85
 
86
-    Route::get("/sales/excel/report", [
87
-        SalesController::class,
88
-        "reportExcel",
89
-    ])->name("sales.excel.report");
86
+    Route::get("/sales/excel/report", [SalesController::class, "reportExcel"]);
90
 
87
 
91
     Route::get("/sales/report", [SalesController::class, "report"]);
88
     Route::get("/sales/report", [SalesController::class, "report"]);
92
 
89