Browse Source

feat: dialog out-transaction

Muhammad Iqbal Afandi 3 years ago
parent
commit
e8abf52b3d

+ 26
- 12
app/Http/Controllers/TransactionController.php View File

@@ -38,14 +38,14 @@ class TransactionController extends Controller
38 38
                 'id' => $transactionOut->id,
39 39
                 'entryCar' => $transactionOut->entryTransaction->created_at,
40 40
                 'outCar' => $transactionOut->created_at,
41
-                'totalTimeParking' => Carbon::parse(
42
-                    $transactionOut->getRawOriginal('created_at')
43
-                )->diffForHumans(
44
-                    $transactionOut->entryTransaction->getRawOriginal('created_at')
41
+                'totalTimeParking' => ParkingFeeService::totalTimeParkingHuman(
42
+                    $transactionOut->entry_transaction_id
43
+                ),
44
+                'totalPriceParking' => ParkingFeeService::totalPriceParkingString(
45
+                    $transactionOut->entry_transaction_id
45 46
                 ),
46
-                'totalPriceParking' => ParkingFeeService::totalPriceParkingString($transactionOut->entry_transaction_id),
47 47
                 'platNumber' => $transactionOut->plat_number,
48
-                'entryTransactionId' => $transactionOut->entry_transaction_id
48
+                'entryTransactionId' => $transactionOut->entry_transaction_id,
49 49
             ]);
50 50
 
51 51
         $typeVehicles = function () {
@@ -54,19 +54,33 @@ class TransactionController extends Controller
54 54
             if ($vehicle) {
55 55
                 return [[
56 56
                     'value' => $vehicle->typeVehicle->id,
57
-                    'label' => $vehicle->typeVehicle->type
57
+                    'label' => $vehicle->typeVehicle->type,
58 58
                 ]];
59 59
             } else {
60 60
                 return TypeVehicle::get()->transform(fn($typeVehicle) => [
61 61
                     'value' => $typeVehicle->id,
62
-                    'label' => $typeVehicle->type
62
+                    'label' => $typeVehicle->type,
63 63
                 ]);
64 64
             }
65 65
         };
66 66
 
67
+        $detailOutTransaction = function () {
68
+            if (request('transaction_number')) {
69
+                return [
70
+                    'totalTimeParking' => ParkingFeeService::totalTimeParkingHuman(
71
+                        request('transaction_number')
72
+                    ),
73
+                    'totalPriceParking' => ParkingFeeService::totalPriceParkingString(
74
+                        request('transaction_number')
75
+                    ),
76
+                ];
77
+            }
78
+        };
79
+
67 80
         return inertia('transaction/Create.vue', compact([
68 81
             'outTransactions',
69
-            'typeVehicles'
82
+            'typeVehicles',
83
+            'detailOutTransaction',
70 84
         ]));
71 85
     }
72 86
 
@@ -93,7 +107,7 @@ class TransactionController extends Controller
93 107
                 'plat_number' => $request->plat_number,
94 108
                 'entry_transaction_id' => $request->entry_transaction_id,
95 109
                 'type_vehicle_id' => $vehicle->type_vehicle_id,
96
-                'user_id' => auth()->user()->id
110
+                'user_id' => auth()->user()->id,
97 111
             ]);
98 112
 
99 113
             return back()->with('success', __('messages.success.store.transaction'));
@@ -105,12 +119,12 @@ class TransactionController extends Controller
105 119
                     'plat_number' => $request->plat_number,
106 120
                     'entry_transaction_id' => $request->entry_transaction_id,
107 121
                     'type_vehicle_id' => $request->type_vehicle_id,
108
-                    'user_id' => auth()->user()->id
122
+                    'user_id' => auth()->user()->id,
109 123
                 ]);
110 124
 
111 125
                 $outTransaction->mutation()->create([
112 126
                     'type' => 1,
113
-                    'amount' => ParkingFeeService::totalPriceParking($request->entry_transaction_id)
127
+                    'amount' => ParkingFeeService::totalPriceParking($request->entry_transaction_id),
114 128
                 ]);
115 129
 
116 130
                 DB::commit();

+ 19
- 13
app/Services/ParkingFeeService.php View File

@@ -9,20 +9,15 @@ use Carbon\Carbon;
9 9
 
10 10
 class ParkingFeeService
11 11
 {
12
-    private static function parkingFee()
13
-    {
14
-        return ParkingFee::get();
15
-    }
16
-
17 12
     private static function parkingPrice()
18 13
     {
19
-        return HelperService::addPrevValue(self::parkingFee()
14
+        return HelperService::addPrevValue(ParkingFee::get()
20 15
                 ->pluck('price')->toArray());
21 16
     }
22 17
 
23 18
     private static function parkingTime()
24 19
     {
25
-        return HelperService::addPrevValue(self::parkingFee()
20
+        return HelperService::addPrevValue(ParkingFee::get()
26 21
                 ->pluck('time_period')->toArray());
27 22
     }
28 23
 
@@ -41,8 +36,8 @@ class ParkingFeeService
41 36
     public static function totalTimeParkingPerDay($entryTransactionId)
42 37
     {
43 38
         return self::totalTimeParkingPerToday($entryTransactionId) > 24
44
-            ? ceil(self::totalTimeParkingPerToday($entryTransactionId) / 24)
45
-            : 0;
39
+        ? ceil(self::totalTimeParkingPerToday($entryTransactionId) / 24)
40
+        : 0;
46 41
     }
47 42
 
48 43
     public static function totalPriceParkingPerDay($entryTransactionId)
@@ -71,16 +66,27 @@ class ParkingFeeService
71 66
     public static function totalTimeParking($entryTransactionId)
72 67
     {
73 68
         return self::totalTimeParkingPerDay($entryTransactionId)
74
-            ? self::totalTimeParkingPerDay($entryTransactionId) . ' Hari'
75
-            : self::totalTimeParkingPerToday($entryTransactionId) . ' Jam';
69
+        ? self::totalTimeParkingPerDay($entryTransactionId) . ' Hari'
70
+        : self::totalTimeParkingPerToday($entryTransactionId) . ' Jam';
71
+    }
76 72
 
73
+    public static function totalTimeParkingHuman($entryTransactionId)
74
+    {
75
+        $entryTransaction = EntryTransaction::where('transaction_number',
76
+            $entryTransactionId)->first();
77
+
78
+        return Carbon::parse(
79
+            now()
80
+        )->diffForHumans(
81
+            $entryTransaction->getRawOriginal('created_at')
82
+        );
77 83
     }
78 84
 
79 85
     public static function totalPriceParking($entryTransactionId)
80 86
     {
81 87
         return self::totalTimeParkingPerDay($entryTransactionId)
82
-            ? self::totalPriceParkingPerDay($entryTransactionId)
83
-            : self::totalPriceParkingPerToday($entryTransactionId);
88
+        ? self::totalPriceParkingPerDay($entryTransactionId)
89
+        : self::totalPriceParkingPerToday($entryTransactionId);
84 90
     }
85 91
 
86 92
     public static function totalPriceParkingString($entryTransactionId)

+ 234
- 17384
public/js/resources_js_pages_transaction_Create_vue.js
File diff suppressed because it is too large
View File


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

@@ -58514,7 +58514,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
58514 58514
 /******/ 		// This function allow to reference async chunks
58515 58515
 /******/ 		__webpack_require__.u = (chunkId) => {
58516 58516
 /******/ 			// return url for filenames based on template
58517
-/******/ 			return "js/" + chunkId + ".js?id=" + {"node_modules_chart_js_auto_auto_esm_js":"10c6b388645ceb22","resources_js_pages_auth_ForgotPassword_vue":"85a497d97d470da0","resources_js_pages_auth_Login_vue":"2cfdf492d60f9521","resources_js_pages_auth_ResetPassword_vue":"9bc29d6465cc0c53","resources_js_pages_auth_VerifyEmail_vue":"f88499b46d5f110c","resources_js_pages_expense_Create_vue":"dd6a278391b58d69","resources_js_pages_expense_Index_vue":"d493dbc863eb491e","resources_js_pages_expense_Show_vue":"222f3f11259e1d74","resources_js_pages_expense_tableHeader_js":"5b2c3a80fb697fff","resources_js_pages_home_Index_vue":"bc20b7148bfb6da0","resources_js_pages_member_Create_vue":"46e5d529878a5a3c","resources_js_pages_member_Edit_vue":"1853671dabd902a7","resources_js_pages_member_Index_vue":"bafaa294b3e6bf60","resources_js_pages_member_tableHeader_js":"61877f698532418e","resources_js_pages_member_useVehicle_js":"8edc972eb134efdf","resources_js_pages_mutation_Report_vue":"f6383687408a3025","resources_js_pages_mutation_tableHeader_js":"2c25ede9c3d1ff83","resources_js_pages_outtransaction_Show_vue":"08d24b9b33538ef7","resources_js_pages_outtransaction_tableHeader_js":"28e044bd873db9aa","resources_js_pages_parkingfee_Create_vue":"a63c4b9f335fb0bf","resources_js_pages_test-transaction_Create_vue":"26c3d63a20969164","resources_js_pages_test-transaction_TableHeader_js":"41de407b819e132e","resources_js_pages_topup_Create_vue":"55f0a1d108219169","resources_js_pages_topup_Index_vue":"36286758cf72350a","resources_js_pages_topup_Show_vue":"8f745baefb670bb6","resources_js_pages_topup_tableHeader_js":"8a585c07bb26d0e7","resources_js_pages_transaction_Create_vue":"8cec47c9a6097cdc","resources_js_pages_transaction_TableHeader_js":"68379a290810960e","resources_js_pages_typemember_Create_vue":"3f3c554a28b716b3","resources_js_pages_typemember_Edit_vue":"51915bbcb5376a36","resources_js_pages_typemember_Index_vue":"6c256e816bd7c375","resources_js_pages_typemember_tableHeader_js":"02f8a6c57093a7fe","resources_js_pages_typemember_useVehicle_js":"9bcdb75c62376835","resources_js_pages_typevehicle_Create_vue":"7d5c9e455cd166ff","resources_js_pages_typevehicle_Edit_vue":"1ab23f2ba50fc7fa","resources_js_pages_typevehicle_Index_vue":"77925b0dddb8b112","resources_js_pages_typevehicle_tableHeader_js":"9616b18c4a750c3f","resources_js_pages_user_Create_vue":"3ee29346cc8b4c3a","resources_js_pages_user_Edit_vue":"3366451aa8c56dcc","resources_js_pages_user_Index_vue":"b2d89eac3119ef58","resources_js_pages_user_Show_vue":"cacd644a884cd355","resources_js_pages_user_tableHeader_js":"78beeea0dcacb81b"}[chunkId] + "";
58517
+/******/ 			return "js/" + chunkId + ".js?id=" + {"node_modules_chart_js_auto_auto_esm_js":"10c6b388645ceb22","resources_js_pages_auth_ForgotPassword_vue":"85a497d97d470da0","resources_js_pages_auth_Login_vue":"2cfdf492d60f9521","resources_js_pages_auth_ResetPassword_vue":"9bc29d6465cc0c53","resources_js_pages_auth_VerifyEmail_vue":"f88499b46d5f110c","resources_js_pages_expense_Create_vue":"dd6a278391b58d69","resources_js_pages_expense_Index_vue":"d493dbc863eb491e","resources_js_pages_expense_Show_vue":"222f3f11259e1d74","resources_js_pages_expense_tableHeader_js":"5b2c3a80fb697fff","resources_js_pages_home_Index_vue":"bc20b7148bfb6da0","resources_js_pages_member_Create_vue":"46e5d529878a5a3c","resources_js_pages_member_Edit_vue":"1853671dabd902a7","resources_js_pages_member_Index_vue":"bafaa294b3e6bf60","resources_js_pages_member_tableHeader_js":"61877f698532418e","resources_js_pages_member_useVehicle_js":"8edc972eb134efdf","resources_js_pages_mutation_Report_vue":"f6383687408a3025","resources_js_pages_mutation_tableHeader_js":"2c25ede9c3d1ff83","resources_js_pages_outtransaction_Show_vue":"08d24b9b33538ef7","resources_js_pages_outtransaction_tableHeader_js":"28e044bd873db9aa","resources_js_pages_parkingfee_Create_vue":"a63c4b9f335fb0bf","resources_js_pages_test-transaction_Create_vue":"26c3d63a20969164","resources_js_pages_test-transaction_TableHeader_js":"41de407b819e132e","resources_js_pages_topup_Create_vue":"55f0a1d108219169","resources_js_pages_topup_Index_vue":"36286758cf72350a","resources_js_pages_topup_Show_vue":"8f745baefb670bb6","resources_js_pages_topup_tableHeader_js":"8a585c07bb26d0e7","resources_js_pages_transaction_Create_vue":"747202830d1a42a1","resources_js_pages_transaction_TableHeader_js":"68379a290810960e","resources_js_pages_typemember_Create_vue":"3f3c554a28b716b3","resources_js_pages_typemember_Edit_vue":"51915bbcb5376a36","resources_js_pages_typemember_Index_vue":"6c256e816bd7c375","resources_js_pages_typemember_tableHeader_js":"02f8a6c57093a7fe","resources_js_pages_typemember_useVehicle_js":"9bcdb75c62376835","resources_js_pages_typevehicle_Create_vue":"7d5c9e455cd166ff","resources_js_pages_typevehicle_Edit_vue":"1ab23f2ba50fc7fa","resources_js_pages_typevehicle_Index_vue":"77925b0dddb8b112","resources_js_pages_typevehicle_tableHeader_js":"9616b18c4a750c3f","resources_js_pages_user_Create_vue":"3ee29346cc8b4c3a","resources_js_pages_user_Edit_vue":"3366451aa8c56dcc","resources_js_pages_user_Index_vue":"b2d89eac3119ef58","resources_js_pages_user_Show_vue":"cacd644a884cd355","resources_js_pages_user_tableHeader_js":"78beeea0dcacb81b"}[chunkId] + "";
58518 58518
 /******/ 		};
58519 58519
 /******/ 	})();
58520 58520
 /******/ 	

+ 65
- 13
resources/js/pages/transaction/Create.vue View File

@@ -1,17 +1,19 @@
1 1
 <script setup>
2 2
 import { watch } from 'vue'
3 3
 import { Inertia } from '@inertiajs/inertia'
4
-import { useForm } from '@inertiajs/inertia-vue3'
4
+import { useForm, Head } from '@inertiajs/inertia-vue3'
5
+import { useConfirm } from 'primevue/useconfirm'
6
+import FormValidationError from '@/utils/formValidationError'
5 7
 import { useFormErrorReset } from '@/components/useFormErrorReset'
6
-import { throttle } from 'lodash'
7 8
 import AppInputText from '@/components/AppInputText.vue'
8 9
 import AppDropdown from '@/components/AppDropdown.vue'
9 10
 import DashboardLayout from '@/layouts/DashboardLayout.vue'
10 11
 import IndexTable from './TableHeader'
11 12
 
12
-defineProps({
13
+const props = defineProps({
13 14
   outTransactions: Object,
14 15
   typeVehicles: Object,
16
+  detailOutTransaction: Object,
15 17
 })
16 18
 
17 19
 const form = useForm({
@@ -32,12 +34,69 @@ watch(
32 34
   }
33 35
 )
34 36
 
37
+const confirm = useConfirm()
38
+
39
+const submitValidation = () => {
40
+  form.clearErrors()
41
+
42
+  const fieldError = []
43
+
44
+  if (!form.plat_number) {
45
+    fieldError.push('plat_number')
46
+  }
47
+
48
+  if (!form.entry_transaction_id) {
49
+    fieldError.push('entry_transaction_id')
50
+  }
51
+
52
+  if (!form.type_vehicle_id) {
53
+    fieldError.push('type_vehicle_id')
54
+  }
55
+
56
+  if (fieldError.length > 0) {
57
+    throw new FormValidationError('Nilai tidak boleh kosong', fieldError)
58
+  }
59
+}
60
+
35 61
 const submit = () => {
36
-  form.post(route('transactions.store'), { onSuccess: () => form.reset() })
62
+  try {
63
+    submitValidation()
64
+
65
+    Inertia.reload({
66
+      only: ['detailOutTransaction'],
67
+      data: { transaction_number: form.entry_transaction_id },
68
+    })
69
+
70
+    confirm.require({
71
+      message: `
72
+      Lama parkir ${props.detailOutTransaction.totalTimeParking},
73
+      biaya yang dikenakan ${props.detailOutTransaction.totalPriceParking}
74
+    `,
75
+      header: 'Tagihan',
76
+      acceptLabel: 'Bayar dan simpan',
77
+      rejectLabel: 'Batalkan',
78
+      accept: () => {
79
+        form.post(route('transactions.store'), {
80
+          onSuccess: () => form.reset(),
81
+        })
82
+      },
83
+      reject: () => {
84
+        confirm.close()
85
+      },
86
+    })
87
+  } catch ($e) {
88
+    if ($e.field) {
89
+      $e.field.forEach((field) => form.setError(field, $e.message))
90
+    }
91
+  }
37 92
 }
38 93
 </script>
39 94
 <template>
95
+  <Head title="Transaksi Keluar" />
96
+
40 97
   <DashboardLayout>
98
+    <ConfirmDialog></ConfirmDialog>
99
+
41 100
     <div class="grid">
42 101
       <div class="col-12">
43 102
         <Card>
@@ -96,21 +155,14 @@ const submit = () => {
96 155
               :stripedRows="true"
97 156
             >
98 157
               <template #header>
99
-                <span style="color: var(--red-600)">
100
-                  Maksimal ditampilkan :
101
-                </span>
158
+                <span style="color: var(--red-600)"> Maksimal ditampilkan : </span>
102 159
                 10
103 160
                 <br />
104 161
                 <span style="color: var(--red-600)">Ditampilkan :</span>
105 162
                 {{ Object.keys(outTransactions).length }}
106 163
               </template>
107 164
 
108
-              <Column
109
-                v-for="value in IndexTable"
110
-                :field="value.field"
111
-                :header="value.header"
112
-                :key="value.field"
113
-              />
165
+              <Column v-for="value in IndexTable" :field="value.field" :header="value.header" :key="value.field" />
114 166
             </DataTable>
115 167
           </template>
116 168
         </Card>