Browse Source

feat: outlet statistics outlet

Muhammad Iqbal Afandi 3 years ago
parent
commit
2517ef5eb9

+ 11
- 1
app/Http/Controllers/DashboardController.php View File

@@ -23,19 +23,25 @@ class DashboardController extends Controller
23 23
     public function __invoke(Request $request)
24 24
     {
25 25
         $transactions = Transaction::filter(['startDate' => today()])->get();
26
+
26 27
         $expenses = Expense::filter(['startDate' => today()])->get();
28
+
27 29
         $laundries = Laundry::get();
30
+
28 31
         $products = Product::get();
29 32
 
30 33
         $transactionChartStatistic = Transaction::get()->groupBy([
31 34
             fn($transaction) => Carbon::parse($transaction->getRawOriginal('created_at'))->format('Y'),
32 35
             fn($transaction) => Carbon::parse($transaction->getRawOriginal('created_at'))->format('M'),
33 36
         ]);
37
+
34 38
         $expenseChartStatistic = Expense::get()->groupBy([
35 39
             fn($expense) => Carbon::parse($expense->getRawOriginal('created_at'))->format('Y'),
36 40
             fn($expense) => Carbon::parse($expense->getRawOriginal('created_at'))->format('M'),
37 41
         ]);
38 42
 
43
+        $transactionOutletChartStatistic = Transaction::get()->groupBy('outlet.name');
44
+
39 45
         return inertia('home/Index', [
40 46
             'cardStatistics' => [
41 47
                 [
@@ -65,7 +71,7 @@ class DashboardController extends Controller
65 71
                     'amount' => $products->count(),
66 72
                 ],
67 73
             ],
68
-            'chartStatistics' => [
74
+            'transactionStatistics' => [
69 75
                 [
70 76
                     'title' => __('words.transaction_statistic'),
71 77
                     'data' => (new TransactionService)->statisticData($transactionChartStatistic),
@@ -75,6 +81,10 @@ class DashboardController extends Controller
75 81
                     'data' => (new ExpenseService)->statisticData($expenseChartStatistic),
76 82
                 ],
77 83
             ],
84
+            'transactionOutletStatistics' => [
85
+                'title' => __('words.transaction_outlet_statistic'),
86
+                'data' => (new TransactionService)->totalPerMonth($transactionOutletChartStatistic),
87
+            ],
78 88
         ]);
79 89
     }
80 90
 }

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

@@ -25,5 +25,6 @@ return [
25 25
     'product_type' => 'Product Type',
26 26
     'transaction_statistic' => 'Transaction Statistic',
27 27
     'expense_statistic' => 'Expense Statistic',
28
+    'transaction_outlet_statistic' => 'Transaction Statistic/Outlet',
28 29
 
29 30
 ];

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

@@ -25,5 +25,6 @@ return [
25 25
     'product_type' => 'Jenis Product',
26 26
     'transaction_statistic' => 'Statistik Transaksi',
27 27
     'expense_statistic' => 'Statistik Pengeluaran',
28
+    'transaction_outlet_statistic' => 'Statistik Transaksi/Outlet',
28 29
 
29 30
 ];

+ 69
- 13
public/js/resources_js_pages_home_Index_vue.js View File

@@ -318,24 +318,25 @@ __webpack_require__.r(__webpack_exports__);
318 318
 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
319 319
   props: {
320 320
     cardStatistics: Object,
321
-    chartStatistics: Object
321
+    transactionStatistics: Object,
322
+    transactionOutletStatistics: Object
322 323
   },
323 324
   setup: function setup(__props, _ref) {
324 325
     var expose = _ref.expose;
325 326
     expose();
326 327
 
327
-    var chartData = function chartData(_chartData) {
328
-      var colors = ['#42A5F5', '#FFA726'];
328
+    var transactionBarData = function transactionBarData(chartData) {
329
+      var colors = ['#17b6ff', '#ffb51c'];
329 330
       var data = {
330 331
         datasets: []
331 332
       };
332 333
       var id = 0;
333 334
 
334
-      for (var key in _chartData) {
335
+      for (var key in chartData) {
335 336
         data.datasets.push({
336 337
           label: key,
337 338
           backgroundColor: colors[id],
338
-          data: _chartData[key]
339
+          data: chartData[key]
339 340
         });
340 341
         id++;
341 342
       }
@@ -343,7 +344,7 @@ __webpack_require__.r(__webpack_exports__);
343 344
       return data;
344 345
     };
345 346
 
346
-    var chartOptions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({
347
+    var transactionBarOption = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({
347 348
       responsive: true,
348 349
       maintainAspectRatio: false,
349 350
       datasetFill: false,
@@ -360,9 +361,41 @@ __webpack_require__.r(__webpack_exports__);
360 361
         }
361 362
       }
362 363
     });
364
+
365
+    var transactionOutletPieData = function transactionOutletPieData(chartData) {
366
+      var labels = [];
367
+      var data = [];
368
+
369
+      for (var key in chartData) {
370
+        labels.push(key);
371
+        data.push(chartData[key]);
372
+      }
373
+
374
+      return {
375
+        labels: labels,
376
+        datasets: [{
377
+          data: data,
378
+          backgroundColor: ['#17b6ff', '#00c3f7', '#00cbdc', '#00d1b2', '#2bd281', '#86cf50', '#c5c623', '#ffb51c']
379
+        }]
380
+      };
381
+    };
382
+
383
+    var transactionOutletPieOption = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({
384
+      maintainAspectRatio: false,
385
+      datasetFill: false,
386
+      plugins: {
387
+        legend: {
388
+          labels: {
389
+            color: '#495057'
390
+          }
391
+        }
392
+      }
393
+    });
363 394
     var __returned__ = {
364
-      chartData: chartData,
365
-      chartOptions: chartOptions,
395
+      transactionBarData: transactionBarData,
396
+      transactionBarOption: transactionBarOption,
397
+      transactionOutletPieData: transactionOutletPieData,
398
+      transactionOutletPieOption: transactionOutletPieOption,
366 399
       ref: vue__WEBPACK_IMPORTED_MODULE_0__.ref,
367 400
       Head: _inertiajs_inertia_vue3__WEBPACK_IMPORTED_MODULE_1__.Head,
368 401
       AppLayout: _layouts_AppLayout_vue__WEBPACK_IMPORTED_MODULE_2__["default"]
@@ -902,6 +935,9 @@ var _hoisted_8 = {
902 935
 var _hoisted_9 = {
903 936
   "class": "col-12 md:col-6"
904 937
 };
938
+var _hoisted_10 = {
939
+  "class": "col-12 md:col-6"
940
+};
905 941
 function render(_ctx, _cache, $props, $setup, $data, $options) {
906 942
   var _component_Card = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("Card");
907 943
 
@@ -938,18 +974,18 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
938 974
         )]);
939 975
       }), 256
940 976
       /* UNKEYED_FRAGMENT */
941
-      )), ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($props.chartStatistics, function (chartStatistic) {
977
+      )), ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($props.transactionStatistics, function (transactionStatistic) {
942 978
         return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_9, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Card, null, {
943 979
           title: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
944
-            return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)((0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(chartStatistic.title), 1
980
+            return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)((0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(transactionStatistic.title), 1
945 981
             /* TEXT */
946 982
             )];
947 983
           }),
948 984
           content: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
949 985
             return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Chart, {
950 986
               type: "bar",
951
-              data: $setup.chartData(chartStatistic.data),
952
-              options: $setup.chartOptions
987
+              data: $setup.transactionBarData(transactionStatistic.data),
988
+              options: $setup.transactionBarOption
953 989
             }, null, 8
954 990
             /* PROPS */
955 991
             , ["data", "options"])];
@@ -962,7 +998,27 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
962 998
         )]);
963 999
       }), 256
964 1000
       /* UNKEYED_FRAGMENT */
965
-      ))])];
1001
+      )), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Card, null, {
1002
+        title: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
1003
+          return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)((0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.transactionOutletStatistics.title), 1
1004
+          /* TEXT */
1005
+          )];
1006
+        }),
1007
+        content: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
1008
+          return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Chart, {
1009
+            type: "pie",
1010
+            width: 600,
1011
+            height: 300,
1012
+            data: $setup.transactionOutletPieData($props.transactionOutletStatistics.data),
1013
+            options: $setup.transactionOutletPieOption
1014
+          }, null, 8
1015
+          /* PROPS */
1016
+          , ["data", "options"])];
1017
+        }),
1018
+        _: 1
1019
+        /* STABLE */
1020
+
1021
+      })])])];
966 1022
     }),
967 1023
     _: 1
968 1024
     /* STABLE */

+ 1
- 1
public/js/vue.js View File

@@ -58088,7 +58088,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
58088 58088
 /******/ 		// This function allow to reference async chunks
58089 58089
 /******/ 		__webpack_require__.u = (chunkId) => {
58090 58090
 /******/ 			// return url for filenames based on template
58091
-/******/ 			return "js/" + chunkId + ".js?id=" + {"node_modules_chart_js_auto_auto_esm_js":"10c6b388645ceb22","resources_js_pages_auth_ForgotPassword_vue":"06e3fde2f6b5dfa3","resources_js_pages_auth_Login_vue":"0d70b4f828bb2ae3","resources_js_pages_auth_ResetPassword_vue":"2ba70d514b47ecff","resources_js_pages_auth_VerifyEmail_vue":"ebac28cf5fb51cfc","resources_js_pages_customer_Create_vue":"1220be5949d46569","resources_js_pages_customer_Edit_vue":"7571072c6961cb67","resources_js_pages_customer_Index_vue":"89aeb69bc7bf9125","resources_js_pages_customer_TableHeader_js":"71be5afdca048a9c","resources_js_pages_discount_Index_vue":"7a73e2119e6e6c6f","resources_js_pages_error_Error_vue":"39121f9961877130","resources_js_pages_expense_Create_vue":"8fa047c8fcff0fa3","resources_js_pages_expense_Index_vue":"b56d8a0027fef24c","resources_js_pages_expense_Show_vue":"e46cf4a28b9e732b","resources_js_pages_expense_TableHeader_js":"72e3dee74175b1c0","resources_js_pages_home_Index_vue":"8f0e1faaa7b884eb","resources_js_pages_laundry_Create_vue":"f5731b3f078c4bff","resources_js_pages_laundry_Edit_vue":"430f285b197d2fc1","resources_js_pages_laundry_Index_vue":"ee761f9e7d6e4502","resources_js_pages_laundry_TableHeader_js":"494e577855bbcaf6","resources_js_pages_mutation_Report_vue":"f53d6840d3891069","resources_js_pages_mutation_TableHeader_js":"82c2999bd7d098a1","resources_js_pages_outlet_Create_vue":"4958b1a88d1e03d1","resources_js_pages_outlet_Edit_vue":"3ce4dea5bd8e134a","resources_js_pages_outlet_Index_vue":"f58972cb6db52f4a","resources_js_pages_outlet_TableHeader_js":"498bf7e64bc0d0c4","resources_js_pages_product_Create_vue":"6f7ae2bf0addfd2c","resources_js_pages_product_Edit_vue":"aec56d000e33fbe6","resources_js_pages_product_Index_vue":"e73d3cd965bdbfb3","resources_js_pages_product_TableHeader_js":"b8eaaa9de25a2322","resources_js_pages_transaction_Create_vue":"04881653c83db0e8","resources_js_pages_transaction_Index_vue":"54a40dce85162abd","resources_js_pages_transaction_Report_vue":"8b3c37b617041b96","resources_js_pages_transaction_Show_vue":"bc1cb7b5161b5386","resources_js_pages_transaction_TableHeader_js":"be63e672e103818b","resources_js_pages_user_Create_vue":"9328027e33f14038","resources_js_pages_user_Edit_vue":"5e97bc1dbb553877","resources_js_pages_user_Index_vue":"bc60d10f530734f1","resources_js_pages_user_Show_vue":"0acbc3d158904cf1","resources_js_pages_user_TableHeader_js":"5653ecbcd70fd235"}[chunkId] + "";
58091
+/******/ 			return "js/" + chunkId + ".js?id=" + {"node_modules_chart_js_auto_auto_esm_js":"10c6b388645ceb22","resources_js_pages_auth_ForgotPassword_vue":"06e3fde2f6b5dfa3","resources_js_pages_auth_Login_vue":"0d70b4f828bb2ae3","resources_js_pages_auth_ResetPassword_vue":"2ba70d514b47ecff","resources_js_pages_auth_VerifyEmail_vue":"ebac28cf5fb51cfc","resources_js_pages_customer_Create_vue":"1220be5949d46569","resources_js_pages_customer_Edit_vue":"7571072c6961cb67","resources_js_pages_customer_Index_vue":"89aeb69bc7bf9125","resources_js_pages_customer_TableHeader_js":"71be5afdca048a9c","resources_js_pages_discount_Index_vue":"7a73e2119e6e6c6f","resources_js_pages_error_Error_vue":"39121f9961877130","resources_js_pages_expense_Create_vue":"8fa047c8fcff0fa3","resources_js_pages_expense_Index_vue":"b56d8a0027fef24c","resources_js_pages_expense_Show_vue":"e46cf4a28b9e732b","resources_js_pages_expense_TableHeader_js":"72e3dee74175b1c0","resources_js_pages_home_Index_vue":"ebcb4cef897548d8","resources_js_pages_laundry_Create_vue":"f5731b3f078c4bff","resources_js_pages_laundry_Edit_vue":"430f285b197d2fc1","resources_js_pages_laundry_Index_vue":"ee761f9e7d6e4502","resources_js_pages_laundry_TableHeader_js":"494e577855bbcaf6","resources_js_pages_mutation_Report_vue":"f53d6840d3891069","resources_js_pages_mutation_TableHeader_js":"82c2999bd7d098a1","resources_js_pages_outlet_Create_vue":"4958b1a88d1e03d1","resources_js_pages_outlet_Edit_vue":"3ce4dea5bd8e134a","resources_js_pages_outlet_Index_vue":"f58972cb6db52f4a","resources_js_pages_outlet_TableHeader_js":"498bf7e64bc0d0c4","resources_js_pages_product_Create_vue":"6f7ae2bf0addfd2c","resources_js_pages_product_Edit_vue":"aec56d000e33fbe6","resources_js_pages_product_Index_vue":"e73d3cd965bdbfb3","resources_js_pages_product_TableHeader_js":"b8eaaa9de25a2322","resources_js_pages_transaction_Create_vue":"04881653c83db0e8","resources_js_pages_transaction_Index_vue":"54a40dce85162abd","resources_js_pages_transaction_Report_vue":"8b3c37b617041b96","resources_js_pages_transaction_Show_vue":"bc1cb7b5161b5386","resources_js_pages_transaction_TableHeader_js":"be63e672e103818b","resources_js_pages_user_Create_vue":"9328027e33f14038","resources_js_pages_user_Edit_vue":"5e97bc1dbb553877","resources_js_pages_user_Index_vue":"bc60d10f530734f1","resources_js_pages_user_Show_vue":"0acbc3d158904cf1","resources_js_pages_user_TableHeader_js":"5653ecbcd70fd235"}[chunkId] + "";
58092 58092
 /******/ 		};
58093 58093
 /******/ 	})();
58094 58094
 /******/ 	

+ 55
- 7
resources/js/pages/home/Index.vue View File

@@ -5,11 +5,12 @@ import AppLayout from '@/layouts/AppLayout.vue'
5 5
 
6 6
 defineProps({
7 7
   cardStatistics: Object,
8
-  chartStatistics: Object,
8
+  transactionStatistics: Object,
9
+  transactionOutletStatistics: Object,
9 10
 })
10 11
 
11
-const chartData = (chartData) => {
12
-  const colors = ['#42A5F5', '#FFA726']
12
+const transactionBarData = (chartData) => {
13
+  const colors = ['#17b6ff', '#ffb51c']
13 14
 
14 15
   const data = {
15 16
     datasets: [],
@@ -29,7 +30,7 @@ const chartData = (chartData) => {
29 30
   return data
30 31
 }
31 32
 
32
-const chartOptions = ref({
33
+const transactionBarOption = ref({
33 34
   responsive: true,
34 35
   maintainAspectRatio: false,
35 36
   datasetFill: false,
@@ -46,6 +47,38 @@ const chartOptions = ref({
46 47
     },
47 48
   },
48 49
 })
50
+
51
+const transactionOutletPieData = (chartData) => {
52
+  const labels = []
53
+  const data = []
54
+
55
+  for (const key in chartData) {
56
+    labels.push(key)
57
+    data.push(chartData[key])
58
+  }
59
+
60
+  return {
61
+    labels: labels,
62
+    datasets: [
63
+      {
64
+        data: data,
65
+        backgroundColor: ['#17b6ff', '#00c3f7', '#00cbdc', '#00d1b2', '#2bd281', '#86cf50', '#c5c623', '#ffb51c'],
66
+      },
67
+    ],
68
+  }
69
+}
70
+
71
+const transactionOutletPieOption = ref({
72
+  maintainAspectRatio: false,
73
+  datasetFill: false,
74
+  plugins: {
75
+    legend: {
76
+      labels: {
77
+        color: '#495057',
78
+      },
79
+    },
80
+  },
81
+})
49 82
 </script>
50 83
 
51 84
 <template>
@@ -74,11 +107,26 @@ const chartOptions = ref({
74 107
         </Card>
75 108
       </div>
76 109
 
77
-      <div v-for="chartStatistic in chartStatistics" class="col-12 md:col-6">
110
+      <div v-for="transactionStatistic in transactionStatistics" class="col-12 md:col-6">
111
+        <Card>
112
+          <template #title>{{ transactionStatistic.title }}</template>
113
+          <template #content>
114
+            <Chart type="bar" :data="transactionBarData(transactionStatistic.data)" :options="transactionBarOption" />
115
+          </template>
116
+        </Card>
117
+      </div>
118
+
119
+      <div class="col-12 md:col-6">
78 120
         <Card>
79
-          <template #title>{{ chartStatistic.title }}</template>
121
+          <template #title>{{ transactionOutletStatistics.title }}</template>
80 122
           <template #content>
81
-            <Chart type="bar" :data="chartData(chartStatistic.data)" :options="chartOptions" />
123
+            <Chart
124
+              type="pie"
125
+              :width="600"
126
+              :height="300"
127
+              :data="transactionOutletPieData(transactionOutletStatistics.data)"
128
+              :options="transactionOutletPieOption"
129
+            />
82 130
           </template>
83 131
         </Card>
84 132
       </div>