Compare commits

...

417 Commits

Author SHA1 Message Date
shancheas 7bb539db0c fix(SPG-1266): Penyesuaian time zone server untuk field pilih waktu - meminimalisasi timezone user/ client 2025-06-25 16:39:01 +07:00
shancheas 92b54635d0 fix(SPG-1262): ONLINE BOOKING - Redirect ke antrian jika tidak sama dengan today - seharusnya diarahkan ke halaman login jika invoice tidak sama dengan today 2025-06-25 15:48:59 +07:00
shancheas 7be4c26ef2 fix(SPG-1270): Pada Invoice/ tagihan booking tambahkan kode booking nya dan informasi booking date dan jumlah yang harus dibayarkan 2025-06-25 15:19:59 +07:00
shancheas 23b3c31810 refactor(SPG-1199): remove unique constraint on item name and update validation logic in item managers 2025-06-25 14:52:41 +07:00
shancheas b96d24de1a feat: add query filter for active booking items in BookingItemManager 2025-06-24 12:44:00 +07:00
shancheas 5d3f9d7bff fix(SPG-1254): ONLINE BOOKING wahana tenant tidak muncul pada catalog online booking 2025-06-24 11:51:43 +07:00
shancheas 831593e743 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-20 14:48:55 +07:00
shancheas 162bd0918f fix: ensure safe access to season period IDs in booking item pricing logic 2025-06-20 14:48:45 +07:00
firmanr 13b5838393 Merge pull request 'feat(SPG-1137): add time group at booking and refund detail' (#161) from feat/otp-cancel into development
Reviewed-on: #161
2025-06-19 18:43:57 +07:00
Firman Ramdhani 63bb55b04b feat(SPG-1137): add time group at booking and refund detail 2025-06-19 18:30:07 +07:00
firmanr 9d1c240b6b Merge pull request 'feat(SPG-1236): setup otp checker guard' (#160) from feat/otp-cancel into development
Reviewed-on: #160
2025-06-19 17:10:07 +07:00
Firman Ramdhani 83f3377465 feat(SPG-1236): setup otp checker guard 2025-06-19 17:09:42 +07:00
firmanr 69c2ee06cf Merge pull request 'feat(SPG-1236): implement otp checker guard on session period' (#159) from feat/otp-cancel into development
Reviewed-on: #159
2025-06-19 17:04:51 +07:00
Firman Ramdhani 42060384aa feat(SPG-1236): implement otp checker guard on session period 2025-06-19 17:04:07 +07:00
firmanr 62cfb1f1a8 Merge pull request 'feat/otp-cancel' (#158) from feat/otp-cancel into development
Reviewed-on: #158
2025-06-19 16:36:52 +07:00
Firman Ramdhani 08a35dfdf4 feat(SPG-1236): implement otp checker guard on booking transaction 2025-06-19 16:32:48 +07:00
Firman Ramdhani 8df836ff3e feat(SPG-1236): implement otp checker guard on session period 2025-06-19 16:24:20 +07:00
Firman Ramdhani 822cfe606a feat(SPG-1236): implement otp checker guard on active and confirm user 2025-06-19 15:55:19 +07:00
Firman Ramdhani de43f0f28b feat(SPG-1236): setup otp checker guard 2025-06-19 15:55:01 +07:00
shancheas 09b0133bf4 fix: update booking item pricing logic to use current rate based on season period IDs 2025-06-19 15:34:12 +07:00
shancheas a77e6b0381 feat: add usage_type field to items and item_queues with corresponding database migration 2025-06-19 14:49:09 +07:00
shancheas a5da557dd9 feat: implement booking expired notification in WhatsApp service 2025-06-19 14:40:17 +07:00
shancheas afad02ba52 fix: temporarily disable OtpAuthGuard in saveToCouch method for transaction data controller 2025-06-17 15:03:17 +07:00
shancheas 6636c596f4 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-17 14:26:50 +07:00
shancheas 01fb358875 feat: enhance transaction read service to include total sales calculation and item ID in quantity query 2025-06-17 14:26:40 +07:00
firmanr f9dc49f7d5 Merge pull request 'feat/otp-cancel' (#157) from feat/otp-cancel into development
Reviewed-on: #157
2025-06-17 09:10:29 +07:00
Firman Ramdhani 1d9cdfe8e6 feat(SPG-1234): add action_type at verifier 2025-06-16 12:20:47 +07:00
Firman Ramdhani ccc363f74f feat(SPG-1234): add action_type at verifier 2025-06-16 12:15:20 +07:00
Firman Ramdhani af1ee2fbee feat(SPG-1234): add action_type at verifier 2025-06-16 12:11:24 +07:00
Firman Ramdhani ec5229645f feat(SPG-1234): add action_type at verifier 2025-06-16 11:48:56 +07:00
shancheas 47d45cb65c feat: integrate CouchDB module across various services and add transaction summary endpoint 2025-06-16 11:27:12 +07:00
shancheas d6717c9c60 feat: add resend notification endpoint in BookingOrderController to send WhatsApp notifications 2025-06-16 09:26:09 +07:00
shancheas d995982203 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-11 19:03:26 +07:00
shancheas 56e475d61f fix: ensure time_group data is only accessed if it exists in BookingOrderController 2025-06-11 19:03:09 +07:00
shancheas 3116acd5ab feat: add image_url to booking item selection in BookingItemManager 2025-06-11 19:02:10 +07:00
firmanr 068c4ce349 Merge pull request 'feat: rename header key basic auth' (#156) from feat/otp-cancel into development
Reviewed-on: #156
2025-06-11 18:28:47 +07:00
Firman Ramdhani 79c9139c3c feat: rename header key basic auth 2025-06-11 18:28:21 +07:00
firmanr d4e8e72af0 Merge pull request 'feat: rename header key basic auth' (#155) from feat/otp-cancel into development
Reviewed-on: #155
2025-06-11 18:15:45 +07:00
Firman Ramdhani 7dd29c2a70 feat: rename header key basic auth 2025-06-11 18:15:09 +07:00
firmanr 0b5b0ce09b Merge pull request 'feat: update validation otp cancel reconciliation' (#154) from feat/otp-cancel into development
Reviewed-on: #154
2025-06-11 17:53:15 +07:00
Firman Ramdhani e1d3ee7188 feat: update validation otp cancel reconciliation 2025-06-11 17:52:18 +07:00
shancheas 838670c822 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-11 16:31:28 +07:00
shancheas 34d8882ec3 feat: make update price public 2025-06-11 16:31:15 +07:00
firmanr 8fb8aac0f9 Merge pull request 'feat: update validation otp cancel reconciliation' (#153) from feat/otp-cancel into development
Reviewed-on: #153
2025-06-11 16:00:02 +07:00
Firman Ramdhani 3a0efb00a9 feat: update validation otp cancel reconciliation 2025-06-11 15:55:21 +07:00
shancheas 737575176e Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-11 15:46:53 +07:00
shancheas f0e8fbddc9 feat: include parent transaction details in booking order retrieval 2025-06-11 15:46:43 +07:00
shancheas d8fa72ba20 feat: implement BookingItemManager for enhanced item booking functionality 2025-06-11 15:41:07 +07:00
firmanr ab9db39a5f Merge pull request 'feat: add feature basic auth request OTP' (#152) from feat/otp-cancel into development
Reviewed-on: #152
2025-06-11 14:58:12 +07:00
Firman Ramdhani 7c45a20866 feat: add feature basic auth request OTP 2025-06-11 14:56:43 +07:00
shancheas 7ff0040f9e refactor: enhance time group data structure in booking order controller 2025-06-11 13:04:32 +07:00
shancheas 9bbd37ba38 refactor: update time group handling in booking order controller 2025-06-11 13:03:48 +07:00
shancheas b476c92b70 feat: add time group information to detail booking 2025-06-11 11:04:41 +07:00
shancheas dc926d84e4 refactor: streamline rescheduling logic and enhance transaction retrieval
- Replaced direct transaction retrieval with a dedicated method for better clarity.
- Consolidated validation checks for rescheduling into the controller.
- Added booking date to the transaction data being created.
- Improved error handling for various transaction states during rescheduling.
2025-06-11 10:35:06 +07:00
shancheas 0172eea573 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-11 08:53:25 +07:00
shancheas 464f5cb49e feat: add booking parent relationship to transactions and implement rescheduling functionality 2025-06-11 08:53:12 +07:00
firmanr 1e395ae53f Merge pull request 'feat: sync time group to couch' (#151) from feat/otp-cancel into development
Reviewed-on: #151
2025-06-10 16:45:26 +07:00
Firman Ramdhani 2f2fc27965 feat: sync time group to couch 2025-06-10 16:44:58 +07:00
irfan 0512c51f8e Merge pull request 'feat: sync time group to couch' (#150) from feat/otp-cancel into development
Reviewed-on: #150
2025-06-10 16:42:59 +07:00
Firman Ramdhani 6da2118ab5 feat: sync time group to couch 2025-06-10 16:38:06 +07:00
shancheas 033ed0046e Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-10 16:34:17 +07:00
shancheas fdbd667b7d feat: enhance loginQueue method to filter orders by date range 2025-06-10 16:34:00 +07:00
shancheas baeb72fe7d feat: add filtering option for items based on time group presence 2025-06-10 16:33:36 +07:00
firmanr 4e2ec4d94f Merge pull request 'feat: save otp code when reject reconciliation' (#149) from feat/otp-cancel into development
Reviewed-on: #149
2025-06-10 16:16:07 +07:00
Firman Ramdhani 94fbec0c78 feat: save otp code when reject reconciliation 2025-06-10 16:02:05 +07:00
firmanr e24fee86ba Merge pull request 'feat/otp-cancel' (#148) from feat/otp-cancel into development
Reviewed-on: #148
2025-06-10 15:19:45 +07:00
Firman Ramdhani 16df6945b7 feat: fix validation generate otp 2025-06-10 15:17:35 +07:00
Firman Ramdhani 8497a5779d feat: fix validation generate otp 2025-06-10 15:02:43 +07:00
shancheas 399ca0bdda Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-10 14:31:07 +07:00
shancheas b8dd2a4e01 temp: update WhatsApp notification method for rescheduling to use OTP notification 2025-06-10 14:30:50 +07:00
shancheas 6a7ab72e12 feat: add booking description field to item model and database 2025-06-10 14:29:46 +07:00
shancheas ffc75ba174 feat: integrate WhatsApp notifications for booking registration and rescheduling 2025-06-10 13:28:58 +07:00
firmanr 18afc47030 Merge pull request 'feat/otp-cancel' (#147) from feat/otp-cancel into development
Reviewed-on: #147
2025-06-10 13:21:34 +07:00
Firman Ramdhani dc1fadbe1f Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/otp-cancel 2025-06-10 13:21:06 +07:00
Firman Ramdhani a1ed81eec5 feat: change length otp checker 2025-06-10 13:20:53 +07:00
shancheas 8192396085 feat: implement reschedule verification process with OTP functionality 2025-06-10 10:26:36 +07:00
shancheas 3661d9d171 feat: increase item limit to 1000 and enhance query for time group filtering 2025-06-09 17:26:57 +07:00
shancheas d4d605d168 feat: add whatsapp notification for booking created 2025-06-09 16:55:55 +07:00
shancheas 10a553ac9d Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2025-06-09 10:11:36 +07:00
shancheas d95f8fd6e5 feat: add time_group_ids filter to item management and DTO 2025-06-09 10:11:16 +07:00
firmanr 9bc2f5fde2 Merge pull request 'feat/otp-cancel' (#146) from feat/otp-cancel into development
Reviewed-on: #146
2025-06-05 17:11:14 +07:00
Firman Ramdhani 0d8ec858eb feat: add api get time group items public 2025-06-05 17:10:33 +07:00
Firman Ramdhani c97399ae8f feat: add api get time group items public 2025-06-05 17:08:39 +07:00
firmanr 5b7df0e372 Merge pull request 'feat: update validation otp' (#145) from feat/otp-cancel into development
Reviewed-on: #145
2025-06-05 16:46:45 +07:00
Firman Ramdhani ca886069f1 feat: update validation otp 2025-06-05 16:45:58 +07:00
firmanr 73c87f6819 Merge pull request 'feat/otp-cancel' (#144) from feat/otp-cancel into development
Reviewed-on: #144
2025-06-05 14:32:34 +07:00
Firman Ramdhani d86f4075d4 feat: rename label kode otp at giving discount report 2025-06-05 12:40:13 +07:00
Firman Ramdhani 88753546b6 feat: add otp column at report, cancel transaction, giving discount, reconciliation, vip_code 2025-06-05 12:12:31 +07:00
Firman Ramdhani cc78dfbd06 feat: monitor log data mapper create discount 2025-06-05 10:17:06 +07:00
Firman Ramdhani f9025faf0b feat: setup message 2025-06-04 22:22:14 +07:00
Firman Ramdhani 6a0b1f6e05 feat: setup verifier 2025-06-04 21:27:34 +07:00
Firman Ramdhani 67129a8c69 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/otp-cancel 2025-06-04 20:18:06 +07:00
Firman Ramdhani 798476aaf5 feat: implement module otp verification 2025-06-04 20:15:24 +07:00
Firman Ramdhani ee52a35af2 feat: implement module otp verification 2025-06-04 20:08:55 +07:00
Firman Ramdhani 538abb122f feat: implement module otp verification 2025-06-04 20:01:23 +07:00
shancheas 36b6ee733f feat: add OTP whatsapp notification 2025-06-04 15:32:05 +07:00
Firman Ramdhani d8cfa97612 fix: add time group at item bundling 2025-06-04 14:41:46 +07:00
Firman Ramdhani 5f08b4be66 feat: setup module otp verifications 2025-06-04 09:48:10 +07:00
Firman Ramdhani 5e328fda1e feat: fix response time group 2025-06-03 15:27:30 +07:00
Firman Ramdhani ffd8595ab2 feat: add column top_code 2025-06-03 14:26:09 +07:00
shancheas 63e43a7ba0 fix: change midtrans id to uuid 2025-06-02 15:33:22 +07:00
shancheas bc8a0407a6 feat: check booking status by id 2025-06-02 14:03:58 +07:00
irfan 9a3d544699 Merge pull request 'feat/SPG-1128-time-group' (#143) from feat/SPG-1128-time-group into development
Reviewed-on: #143
2025-06-02 13:47:45 +07:00
Firman Ramdhani 845e0547ab feat(SPG-1133): penambahan kolom dan filter time group di report income per item dan report income per item master 2025-05-28 18:26:52 +07:00
Firman Ramdhani 9e5d59baac feat: add table relation at event handler item 2025-05-28 17:13:13 +07:00
Firman Ramdhani 89dc1fc160 feat: add relation time group at handle update item 2025-05-28 17:04:26 +07:00
Firman Ramdhani 16bbb1f02b feat(SPG-1140): menambahkan validasi end time untuk create dan update time group 2025-05-28 16:00:58 +07:00
Firman Ramdhani 339b2bdab6 feat: menambahkan validasi end time untuk create dan update time group 2025-05-28 15:48:36 +07:00
Firman Ramdhani a80e2e3419 feat: memasangkan time group di item rate, item, dan item antrian 2025-05-28 15:08:38 +07:00
Firman Ramdhani 3b362d2822 feat: crete API CRUD feature time group 2025-05-28 14:52:26 +07:00
shancheas b4f39d5ccf feat: booking online response add midtrans url 2025-05-28 13:35:19 +07:00
shancheas 7c5b1b3aa8 feat: api for booking online 2025-05-28 12:32:11 +07:00
irfan 9e361da9cb Merge pull request 'development-local' (#141) from development-local into development
Reviewed-on: #141
2025-05-27 13:27:22 +07:00
shancheas 94e769795a fix: add version to booking api 2025-05-27 13:26:41 +07:00
shancheas 968697ee17 feat: add check period to public url 2025-05-27 11:51:54 +07:00
irfan 0757d6791d Merge pull request 'feat/report-income' (#138) from feat/report-income into development
Reviewed-on: #138
2025-05-27 11:36:27 +07:00
irfan a438cc5f83 Merge pull request 'feat: booking online OTP and item' (#140) from development-local into development
Reviewed-on: #140
2025-05-27 11:35:10 +07:00
shancheas 2dd0bd45a8 feat: booking online OTP and item 2025-05-27 11:11:08 +07:00
Firman Ramdhani 027025935c feat: add column and filter payment reference at report income 2025-05-19 17:42:35 +07:00
Firman Ramdhani 10cd1a711e feat: merubah tanggal pendapat di report pembalatan ke created_at 2025-05-16 18:37:40 +07:00
irfan bad4b2ea56 Merge pull request 'development' (#137) from development into production
Reviewed-on: #137
2025-05-09 23:33:05 +00:00
irfan 35919b91f7 Merge pull request 'refactor: replace CouchService with CouchModule in transaction modules' (#136) from development-local into development
Reviewed-on: #136
2025-05-09 23:32:40 +00:00
shancheas 8afbe33c01 refactor: replace CouchService with CouchModule in transaction modules 2025-05-10 06:31:57 +07:00
irfan f2d7ea80d2 Merge pull request 'development' (#135) from development into production
Reviewed-on: #135
2025-05-09 23:00:20 +00:00
irfan b18a834129 Merge pull request 'feat: enhance transaction calculations in CouchService and SalesPriceFormulaDataService' (#134) from development-local into development
Reviewed-on: #134
2025-05-09 22:59:35 +00:00
shancheas 928e2e7648 feat: enhance transaction calculations in CouchService and SalesPriceFormulaDataService 2025-05-09 17:56:30 +07:00
irfan 9b1f945873 Merge pull request 'development' (#133) from development into production
Reviewed-on: #133
2025-05-08 23:47:06 +00:00
irfan 6882314a9e Merge pull request 'development-local' (#132) from development-local into development
Reviewed-on: #132
2025-05-08 23:44:49 +00:00
shancheas 94baf956dd feat: add env to active skip transaction feature 2025-05-09 06:44:17 +07:00
shancheas e92f325807 fix: make transaction setting public 2025-05-02 11:25:33 +07:00
shancheas 66d76634b7 fix: find transactionSettingData with parameter 2025-05-02 09:02:45 +07:00
shancheas b91080906e feat: change save factor formula 2025-05-02 07:33:08 +07:00
shancheas 714b075e1d fix: add transaction setting api 2025-04-30 13:06:36 +07:00
shancheas da024606ff feat: add logic to skip save transaction 2025-04-30 07:46:19 +07:00
irfan 0b482be669 Merge pull request 'feat: add clear couch transaction API' (#131) from development into production
Reviewed-on: #131
2025-04-14 06:50:43 +00:00
shancheas 064112e731 feat: add clear couch transaction API 2025-04-14 12:06:05 +07:00
irfan 05473fce3d Merge pull request 'fix: time not null when save queue' (#130) from development into production
Reviewed-on: #130
2025-04-03 15:11:57 +00:00
shancheas d6a238a224 fix: time not null when save queue 2025-04-03 22:11:19 +07:00
irfan a8b3f67d1b Merge pull request 'development' (#129) from development into production
Reviewed-on: #129
2025-04-03 14:55:42 +00:00
shancheas dc5e938f75 feat: add configuration to show estimation queue time 2025-04-03 21:54:35 +07:00
shancheas eb4da7ccc4 temp: remove multiple admin login validation from queue admin 2025-04-03 21:54:04 +07:00
irfan bef9f99f13 Merge pull request 'fix: add error log to whatsapp service' (#128) from development into production
Reviewed-on: #128
2025-01-30 00:02:59 +00:00
shancheas 46caaba6bd fix: add error log to whatsapp service 2025-01-30 07:01:52 +07:00
irfan 8e0c8462b9 Merge pull request 'fix: throw error when display id is undefined' (#127) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #127
2025-01-23 15:15:43 +00:00
shancheas 7953c7dbbd fix: validate display uuid
continuous-integration/drone/push Build is passing Details
2025-01-23 22:15:26 +07:00
shancheas 6911f6f0a2 fix: don't send whatsapp notification when phone is null
continuous-integration/drone/push Build is passing Details
2025-01-23 22:11:15 +07:00
shancheas 762340a72b fix: throw error when display id is undefined
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-23 21:49:33 +07:00
irfan 00e2b6e015 Merge pull request 'feat: add text to speech api' (#126) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #126
2025-01-17 11:04:20 +00:00
shancheas 61cbbf81ef feat: add text to speech api
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-16 12:12:26 +07:00
irfan 7b864d4163 Merge pull request 'fix: average time from float to bigint' (#125) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #125
2025-01-15 03:50:38 +00:00
shancheas 4ea53f7088 fix: average time from float to bigint
continuous-integration/drone/push Build is passing Details
2025-01-15 10:49:56 +07:00
irfan 00ec2c9342 Merge pull request 'fix: add optional id when map transaction' (#124) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #124
2025-01-13 10:20:15 +00:00
shancheas 0548141e5f fix: add optional id when map transaction
continuous-integration/drone/push Build is passing Details
2025-01-13 17:19:50 +07:00
irfan 440a589f8a Merge pull request 'development' (#123) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #123
2025-01-13 08:25:13 +00:00
shancheas 29e4dc5400 fix: code not generate because vip pass
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-13 14:10:32 +07:00
shancheas f9d8f85179 fix: moment js when generate
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-13 13:31:19 +07:00
shancheas 769e8174f4 fix: don't create queue from POS
continuous-integration/drone/push Build is passing Details
2025-01-13 12:59:30 +07:00
shancheas 3ace59c450 feat: create queue using API
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-13 12:42:57 +07:00
irfan a51b6ea520 Merge pull request 'fix: play estimation to numeric' (#122) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #122
2025-01-03 11:09:13 +00:00
shancheas 187555a543 fix: play estimation to numeric
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2025-01-03 17:40:21 +07:00
irfan 750cee8853 Merge pull request 'fix: call time stop when time is more than estimation' (#121) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #121
2024-12-24 21:59:28 +00:00
shancheas 551bd12f5b fix: call time stop when time is more than estimation
continuous-integration/drone/push Build is passing Details
2024-12-25 04:57:28 +07:00
irfan 0a98bcfd59 Merge pull request 'fix: error when send to null phone number' (#120) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #120
2024-12-24 21:27:30 +00:00
shancheas 1692c8234a fix: error when send to null phone number
continuous-integration/drone/push Build is passing Details
2024-12-25 04:26:12 +07:00
irfan 9a612cc025 Merge pull request 'fix: whatsapp notification not show' (#119) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #119
2024-12-22 15:36:34 +00:00
shancheas 903b7cfd18 fix: whatsapp notification not show
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-22 09:33:22 +07:00
irfan 3aee1fdfc9 Merge pull request 'fix: register queue still sen notification' (#118) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #118
2024-12-21 22:55:53 +00:00
shancheas 26a6af2044 fix: register queue still sen notification
continuous-integration/drone/push Build is passing Details
2024-12-22 05:42:28 +07:00
irfan 0afaf1d195 Merge pull request 'development' (#117) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #117
2024-12-20 22:28:26 +00:00
shancheas d7ed77934d temp: remove log
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-21 05:26:16 +07:00
shancheas 66720c5b8b feat: implement requiring call notification 2024-12-21 05:20:25 +07:00
shancheas 44e74de315 feat: whatsapp notification
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-21 04:01:54 +07:00
shancheas 82e7879969 feat: add configuration for whatsapp service 2024-12-21 03:56:13 +07:00
irfan ceedf83385 Merge pull request 'development' (#116) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #116
2024-12-17 15:52:40 +00:00
shancheas d612b6725a fix: login by new transaction receipt id
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-17 19:27:07 +07:00
shancheas 54b9658075 fix: show queue only same day 2024-12-17 19:26:22 +07:00
irfan 13ae23000f Merge pull request 'development' (#115) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #115
2024-12-10 23:02:47 +00:00
shancheas 661dbb8cf2 fix: add peak level
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-10 15:55:27 +07:00
shancheas 6dc6579450 feat: add item id
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details
2024-12-10 14:19:24 +07:00
shancheas e3db958e0d fix: error ticket not found when split queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details
2024-12-10 14:00:38 +07:00
shancheas d73752252a feat: peak level base on configuration
continuous-integration/drone/push Build is passing Details
2024-12-10 13:51:28 +07:00
shancheas b38c489777 fix: last item queue time
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-10 12:27:34 +07:00
shancheas 8cfc003261 feat: add query name filter to items
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-10 11:57:33 +07:00
shancheas 55e89426d9 feat(SPG-1078): summary all item queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-03 14:27:12 +07:00
shancheas 5f6214eeb6 feat: add max peak level and call prepare call time to item queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-12-03 11:21:44 +07:00
shancheas d71c2096b8 fix: done queue not update call time 2024-12-03 11:05:03 +07:00
shancheas f661276c58 fix: calculate average time when no queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-28 17:18:33 +07:00
shancheas 4a3e77043e fix: parent qty not reduce when split QR
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-28 11:24:31 +07:00
shancheas b4f141e628 feat(SPG-1061): add bundling to queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-26 12:40:02 +07:00
shancheas 9db5c4b326 feat: add queue recommendations
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-26 10:31:06 +07:00
shancheas f7e3d5399c fix(SPG-1055): update QR when customer and phone exist
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-22 18:51:22 +07:00
shancheas 7305dfd068 fix(SPG-1060): order queue by time
continuous-integration/drone/push Build is passing Details
2024-11-22 17:27:05 +07:00
shancheas b4bc31463e fix(SPG-1049): add order to queue item
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-22 14:49:42 +07:00
shancheas 83d53847d7 feat: add estimation time
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-22 10:54:51 +07:00
shancheas e09190df42 fix: time empty when no queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-21 18:48:49 +07:00
shancheas 61045a39ab fix(SPG-1027): total ticket not match
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-21 18:28:25 +07:00
shancheas 60b5bcf638 fix: time calculation customer
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-21 17:51:45 +07:00
shancheas 4eedca12e7 fix(SPG-1044): validate split QR when phone and username exist
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-21 11:31:29 +07:00
shancheas cb452cf5f3 fix(SPG-1045): send rest qty instead all qty 2024-11-21 11:30:31 +07:00
shancheas ea25e0cae1 fix(SPG-1047): merge item queue with same item 2024-11-21 10:39:20 +07:00
shancheas 5e4401a974 fix: queue time string to number
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 18:06:28 +07:00
shancheas c05af5c16b fix: admin queue time
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 17:51:47 +07:00
shancheas 5988a592ac fix: merge new order queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 17:41:29 +07:00
shancheas 1148a72481 fix: total QR header
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 17:33:00 +07:00
shancheas 3b7d7ea80b fix: don't merge queue when customer name is empty
continuous-integration/drone/push Build is passing Details
2024-11-20 14:44:19 +07:00
shancheas 3b19484f29 fix(SPG-1030): merge queue when user is exits
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 12:50:58 +07:00
shancheas 4dc21c4ebd fix(SPG-1036): remove queue if empty
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 11:46:19 +07:00
shancheas 99d0fc8560 fix(SPG-1035): grouping queue information
continuous-integration/drone/push Build is passing Details
2024-11-20 11:38:23 +07:00
shancheas ac3fde14e3 feat: add total_queue_item to summary ticket
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-20 10:40:23 +07:00
shancheas 8d54c686fc fix(SPG-1027): Total QR not same with total ticket 2024-11-20 10:40:00 +07:00
shancheas c0a68db9f1 fix: total activities, now merge by item queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-19 13:33:45 +07:00
shancheas 3cf4fbdada fix: exclude privilege from admin queue 2024-11-19 13:33:29 +07:00
shancheas 9eacb7dca5 feat: add done status queue 2024-11-19 13:16:52 +07:00
shancheas eae529bce9 fix: vip pass queue register for 1 queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-19 11:13:53 +07:00
shancheas a0de16575f fix: empty queue id in time formula
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-15 13:51:12 +07:00
shancheas 53ef4656eb fix: change queue time formula to manager
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-15 12:37:43 +07:00
shancheas ec916ab574 fix: queue time calculation
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-15 11:16:29 +07:00
shancheas 72827aa83e feat: calculate time queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-15 11:05:34 +07:00
shancheas 0e9ae569ba debug: add log time to queue admin
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-15 10:23:06 +07:00
shancheas 37334ecb19 fix: queue admin item not show 2024-11-14 16:10:31 +07:00
shancheas 86c73058fd feat: add information to queue item for display
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-14 15:05:39 +07:00
shancheas fb7f925c78 feat: add session to admin queue 2024-11-14 14:24:56 +07:00
shancheas 2b132c53a8 feat: add average item queue time
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-14 10:06:51 +07:00
shancheas e9535749d4 fix: vip code prefix
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2024-11-13 18:18:04 +07:00
shancheas 94696e765d fix: request ticket item 2024-11-13 18:17:53 +07:00
shancheas 9805b9903a feat: add pos item ticket
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-13 16:49:05 +07:00
shancheas af9818d44c feat: cancel order, delete queue
continuous-integration/drone/push Build is passing Details
2024-11-13 15:48:54 +07:00
shancheas 2bcd7a34fb feat: create summary ticket function 2024-11-13 15:48:30 +07:00
shancheas 577f8ea9ea feat: login by receipt
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-13 14:30:23 +07:00
shancheas 1878d03c0f feat: vip auto generate queue 2024-11-13 14:30:10 +07:00
shancheas 6807d00cbe fix: add empty user to base 2024-11-13 14:29:35 +07:00
shancheas ad3e3593fd feat: add gate log
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-13 10:00:37 +07:00
shancheas 8e7e43b09d fix: vip from booking generate queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-11 16:34:58 +07:00
shancheas 6c53610ec4 feat: vip auto enter queue
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-11 14:43:15 +07:00
shancheas c129a59d47 feat: merge item queue 2024-11-11 14:29:17 +07:00
shancheas d413f1fa7b fix: QR queue and date booking
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-08 15:13:33 +07:00
shancheas bf5914af92 fix: queue bucket item id
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-06 12:01:49 +07:00
shancheas 28c1ab36da fix: summary ticket without order
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-06 11:38:51 +07:00
shancheas 3ed25e1366 fix: admin queue order item
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-06 11:28:54 +07:00
shancheas 4c403293db fix: admin queue order item
continuous-integration/drone/push Build is passing Details
2024-11-06 11:28:02 +07:00
shancheas dac42b754c fix: missing logic
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-06 11:06:14 +07:00
shancheas 5ef7521e9b feat: add queue active summary
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-05 14:43:04 +07:00
shancheas ba7b81c320 feat: add login by invoice code
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-04 16:34:17 +07:00
shancheas 7137b98043 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-04 15:06:24 +07:00
shancheas 3ddd837622 fix: customer and phone in split queue 2024-11-04 15:06:09 +07:00
firmanr 217362193a Merge pull request 'feat/report-demography' (#113) from feat/report-demography into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #113
2024-11-04 07:08:22 +00:00
firmanr 51be95b5ff Merge pull request 'feat: update report demography' (#114) from feat/report-demography into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #114
2024-11-04 07:08:09 +00:00
Firman Ramdhani a3647b536b feat: update report demography
continuous-integration/drone/push Build is passing Details
2024-11-04 14:01:37 +07:00
shancheas 5f46432327 feat: login customer
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-04 12:35:53 +07:00
shancheas 319d9eecef Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-11-01 13:33:43 +07:00
shancheas 50e7f66bb7 feat: split QR customer 2024-11-01 13:33:25 +07:00
shancheas 492a4ca2ba wip: queue bucket 2024-11-01 13:32:59 +07:00
Supan Adit Pratama 4ed7ecce5e ci: fix filtering
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-30 14:38:11 +07:00
Supan Adit Pratama e6787aed89 ci: fix duplicate step name
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2024-10-30 14:37:42 +07:00
Supan Adit Pratama 1d54b709b6 ci: build k8s only
continuous-integration/drone/push Build encountered an error Details
continuous-integration/drone/tag Build encountered an error Details
2024-10-30 14:37:07 +07:00
Supan Adit Pratama bd32d4fbdd ci: fix depends
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2024-10-30 14:34:27 +07:00
Supan Adit Pratama 78fb5b7fac ci: update pipeline for kustomize auto
continuous-integration/drone/push Build encountered an error Details
continuous-integration/drone/tag Build encountered an error Details
2024-10-30 14:33:50 +07:00
shancheas dea9989914 fix: queue not generate from POS
continuous-integration/drone/push Build is passing Details
2024-10-30 13:54:09 +07:00
shancheas c8d0b32cc6 feat: add list order queue
continuous-integration/drone/push Build is passing Details
2024-10-29 14:15:37 +07:00
shancheas 93b1208278 refactor: change code to manager
continuous-integration/drone/push Build is passing Details
2024-10-29 10:30:57 +07:00
shancheas 86251f43a2 fix: change register ticket body
continuous-integration/drone/push Build is passing Details
2024-10-28 17:16:41 +07:00
shancheas 9977a7456a feat: item queue id in response ticket
continuous-integration/drone/push Build is passing Details
2024-10-28 16:03:13 +07:00
shancheas 487f59ae93 feat: add register queue
continuous-integration/drone/push Build is passing Details
2024-10-28 15:09:27 +07:00
shancheas e9de46fff8 fix: change response queue to pagination
continuous-integration/drone/push Build is passing Details
2024-10-25 16:11:43 +07:00
shancheas 5b507a1c3c feat: add queue admin list
continuous-integration/drone/push Build is passing Details
2024-10-25 14:49:56 +07:00
shancheas 143bf76417 fix: ticket item request url
continuous-integration/drone/push Build is passing Details
2024-10-24 16:05:42 +07:00
shancheas ac86289182 feat: add detail item ticket
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-24 13:25:56 +07:00
shancheas 32d4064f0a feat: add detail queue item
continuous-integration/drone/push Build is passing Details
2024-10-23 17:16:28 +07:00
shancheas 01b2796c26 feat: order tickets
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-23 11:56:21 +07:00
shancheas e9d864c922 feat: add login queue customer 2024-10-23 10:30:14 +07:00
shancheas d6c02ac29f fix: on delete queue item
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-22 14:36:14 +07:00
shancheas 4f0b378ec6 fix: missing transaction handler
continuous-integration/drone/push Build encountered an error Details
2024-10-22 13:30:49 +07:00
shancheas efa245048a feat: item queue module
continuous-integration/drone/push Build encountered an error Details
continuous-integration/drone/tag Build is passing Details
2024-10-22 11:47:55 +07:00
shancheas 2d0ccf67f2 WIP: module Queue 2024-10-22 11:47:22 +07:00
shancheas 77cf19c06e fix: unused code 2024-10-22 11:45:44 +07:00
shancheas 77a6afbbbc fix: add video extension
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-21 12:59:44 +07:00
irfan fea0420ae4 Merge pull request 'development' (#112) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #112
2024-10-19 18:35:05 +00:00
shancheas 3eee8d73f4 fix: recap transaction
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-20 01:33:31 +07:00
shancheas 07d2ec3b46 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-17 15:28:01 +07:00
shancheas 8ba5646bb6 fix: show video url in item and vip pass in vip category 2024-10-17 15:27:43 +07:00
irfan ce1aa86944 Merge pull request 'development' (#111) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #111
2024-10-16 15:42:27 +00:00
irfan 4d20955764 Merge pull request 'feat: update filter report' (#110) from feat/update-filter-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #110
2024-10-16 12:31:48 +00:00
Firman Ramdhani 6a8816aa90 feat: update filter report
continuous-integration/drone/push Build is passing Details
2024-10-16 18:31:55 +07:00
shancheas 8f43907091 feat: add vip pass and video url to item
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-16 17:01:47 +07:00
irfan 7afe06e96c Merge pull request 'fix: get tax formula active only' (#109) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #109
2024-10-14 19:18:00 +00:00
shancheas c0a0b2316d fix: get tax formula active only
continuous-integration/drone/push Build is passing Details
2024-10-15 02:17:13 +07:00
irfan 95ee8dce8d Merge pull request 'development' (#108) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #108
2024-10-09 18:22:03 +00:00
Firman Ramdhani 55ddc9b605 feat(SPG-997): add report vip code
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-09 17:59:20 +07:00
Firman Ramdhani e2a6878e71 feat(SPG-997): add report vip code
continuous-integration/drone/push Build is passing Details
2024-10-09 17:48:31 +07:00
Firman Ramdhani f2c409fc35 feat: adjustment default sorting on report income per item and report per item master
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-09 15:58:13 +07:00
Firman Ramdhani 7213e7915b feat: adjustment default sorting on report income per item and report per item master
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2024-10-09 14:57:20 +07:00
Firman Ramdhani 0e65fb8a9a feat(SPG-992): penyesuaian kolom total tunai di report reconcile
continuous-integration/drone/push Build is passing Details
2024-10-09 14:49:22 +07:00
shancheas 6efe5618cb Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2024-10-09 12:49:56 +07:00
shancheas 60167cd807 fix: change bundling item edit from item_id to total_net_price 2024-10-09 12:49:34 +07:00
Firman Ramdhani 0dfaeb2045 feat: add low level order
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-08 20:00:09 +07:00
shancheas 18dc15e442 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-08 16:27:20 +07:00
shancheas 198dcb4933 feat: add discount value to vip code 2024-10-08 16:26:40 +07:00
shancheas 901c67137b feat: calculate discount for bundling 2024-10-08 15:40:54 +07:00
Firman Ramdhani 411458fe4c feat: add pos name and pos number at report reconciliation
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-07 12:58:31 +07:00
Firman Ramdhani d911f80ff9 feat: add pos name and pos number at report reconciliation
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-10-07 10:40:47 +07:00
irfan 79f3966b49 Merge pull request 'development' (#107) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #107
2024-10-06 23:00:03 +00:00
shancheas e6066b534c fix: add capture error when calculate pos formula
continuous-integration/drone/push Build is passing Details
2024-10-07 05:58:45 +07:00
shancheas c5590ab7b1 fix: pos formula calculation
continuous-integration/drone/push Build is passing Details
2024-10-07 05:54:06 +07:00
irfan 1a633cc574 Merge pull request 'development' (#105) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #105
2024-10-04 04:12:22 +00:00
firmanr 1348f5a79b Merge pull request 'feat: create report demography' (#106) from feat/report-realtime into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #106
2024-10-04 03:38:51 +00:00
Firman Ramdhani 90ab3668b4 feat: create report demography
continuous-integration/drone/push Build is passing Details
2024-10-04 10:38:12 +07:00
firmanr 49b98cd56c Merge pull request 'feat: add module report summary' (#104) from feat/report-realtime into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #104
2024-10-01 15:05:38 +00:00
Firman Ramdhani d6ae891de4 feat: add module report summary
continuous-integration/drone/push Build is passing Details
2024-10-01 22:03:59 +07:00
irfan 9026f85a66 Merge pull request 'development' (#103) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #103
2024-09-29 12:01:23 +00:00
shancheas d40261e919 fix: report query from text to uuid
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-09-29 10:59:55 +07:00
shancheas e1c6b809e4 fix: add cookie when request superset token
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-09-28 12:45:13 +07:00
irfan c47f1e2616 Merge pull request 'feat: add cancel transaction report' (#102) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #102
2024-09-27 10:17:42 +00:00
shancheas df0536157a feat: add cancel transaction report
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-09-25 06:40:03 +07:00
irfan 92bf8fc342 Merge pull request 'fix: discount percent calculation' (#101) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #101
2024-09-21 18:10:34 +00:00
shancheas 437793a2a1 fix: discount percent calculation
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build was killed Details
2024-09-22 01:09:54 +07:00
irfan 48a48e6e7a Merge pull request 'development' (#100) from development into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #100
2024-09-21 16:08:58 +00:00
shancheas 22f4e732db fix: transaction NaN without discount
continuous-integration/drone/push Build is passing Details
2024-09-21 23:04:59 +07:00
shancheas 34ae5964c4 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
2024-09-21 07:24:34 +07:00
shancheas f2fef65f20 fix: change total price to net price 2024-09-21 07:24:16 +07:00
firmanr 039531de3b Merge pull request 'feat: move tipe item' (#99) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #99
2024-09-20 12:01:57 +00:00
Firman Ramdhani 0b8bb72392 feat: move tipe item
continuous-integration/drone/push Build is passing Details
2024-09-20 19:01:18 +07:00
firmanr 256c8f38bd Merge pull request 'feat: update report' (#98) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #98
2024-09-20 11:36:16 +00:00
Firman Ramdhani 109898b076 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/adjustment-report
continuous-integration/drone/push Build is passing Details
2024-09-20 18:34:58 +07:00
shancheas b2be2e0160 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
2024-09-20 18:33:11 +07:00
shancheas b4266d5d68 fix: add discount to calculator 2024-09-20 18:32:52 +07:00
Firman Ramdhani f23a9f3510 feat: update report
continuous-integration/drone/push Build is passing Details
2024-09-20 18:32:17 +07:00
firmanr 91370940d7 Merge pull request 'feat: fix filter report' (#97) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #97
2024-09-20 10:51:25 +00:00
Firman Ramdhani c15b4d8079 feat: fix filter report
continuous-integration/drone/push Build is passing Details
2024-09-20 17:25:28 +07:00
shancheas b16edb73e3 fix: report wrong non bundling profit share key
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-09-20 13:01:38 +07:00
firmanr ea58096287 Merge pull request 'feat/adjustment-report' (#96) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #96
2024-09-20 04:50:52 +00:00
Firman Ramdhani 1dfcaf7b15 feat(SPG-969): feat set default payment_date_bank
continuous-integration/drone/push Build is passing Details
2024-09-20 11:50:34 +07:00
Firman Ramdhani 8b58598955 feat(SPG-969): feat set default payment_date_bank
continuous-integration/drone/push Build is passing Details
2024-09-20 11:49:58 +07:00
firmanr 5eb50c952f Merge pull request 'feat/adjustment-report' (#95) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #95
2024-09-20 04:33:19 +00:00
Firman Ramdhani aaa0ca6f76 feat: fix report bug and create report tax
continuous-integration/drone/push Build is passing Details
2024-09-20 11:32:48 +07:00
irfan 3de7bfbbe5 Merge pull request 'fix/price-calculator' (#94) from fix/price-calculator into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #94
2024-09-20 04:07:24 +00:00
shancheas 60c03fefa0 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into fix/price-calculator
continuous-integration/drone/push Build is passing Details
2024-09-20 11:06:31 +07:00
shancheas b34d54e7d0 fix: item bundling replace when edit 2024-09-20 11:06:09 +07:00
Firman Ramdhani 3fd97b8879 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/adjustment-report
continuous-integration/drone/push Build is passing Details
2024-09-20 09:46:25 +07:00
irfan 93c822f34e Merge pull request 'fix/price-calculator' (#93) from fix/price-calculator into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #93
2024-09-19 12:34:03 +00:00
shancheas e09c76309e fix: formula calculation
continuous-integration/drone/push Build is passing Details
2024-09-19 19:33:28 +07:00
Firman Ramdhani 43deb04d92 feat(SPG-966): fix report income
continuous-integration/drone/push Build is passing Details
2024-09-19 18:22:19 +07:00
shancheas 23043fb7f9 feat: change logic to save formula 2024-09-19 17:52:50 +07:00
Firman Ramdhani 1d377b574c feat(SPG-966): fix report income
continuous-integration/drone/push Build is passing Details
2024-09-19 17:50:11 +07:00
Firman Ramdhani 7d9f619858 feat(SPG-966): fix report income 2024-09-19 17:49:35 +07:00
shancheas c06a2a0a2b Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into fix/price-calculator 2024-09-19 14:07:37 +07:00
shancheas cc71814648 fix: bulk transaction action
continuous-integration/drone/push Build is passing Details
2024-09-18 17:25:07 +07:00
irfan 004dfc9de5 Merge pull request 'feat/adjustment-report' (#92) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #92
2024-09-18 10:14:59 +00:00
Firman Ramdhani 09d6dbaab2 feat: remove console on auth
continuous-integration/drone/push Build is passing Details
2024-09-18 16:30:23 +07:00
Firman Ramdhani c76594d767 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/adjustment-report
continuous-integration/drone/push Build is passing Details
2024-09-18 16:25:39 +07:00
Firman Ramdhani f4cf5178b8 feat: change auth concept
continuous-integration/drone/push Build is passing Details
2024-09-18 16:25:29 +07:00
shancheas ffbbf6e140 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/push Build is passing Details
2024-09-18 13:55:57 +07:00
shancheas 614a9346fb feat: price calculator 2024-09-18 13:55:47 +07:00
irfan f7c49d27d5 Merge pull request 'fix/income-report' (#91) from fix/income-report into development
continuous-integration/drone/push Build was killed Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #91
2024-09-13 10:39:52 +00:00
irfan 2ee96a617f fix: income item breakdown report
continuous-integration/drone/push Build was killed Details
2024-09-13 10:39:04 +00:00
irfan 10049abc55 fix: income item report
continuous-integration/drone/push Build is passing Details
2024-09-13 10:38:32 +00:00
irfan 01fbedab77 fix: income report
continuous-integration/drone/push Build is passing Details
2024-09-13 10:37:15 +00:00
irfan b2659def9a ci: rollback to yarn, NPM is s*ck
continuous-integration/drone/push Build is passing Details
2024-09-13 03:55:52 +00:00
firmanr d597734467 Merge pull request 'feat: exclude privilege logout' (#90) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details
Reviewed-on: #90
2024-09-13 03:49:40 +00:00
Firman Ramdhani 27a0c56af7 feat: exclude privilege logout
continuous-integration/drone/push Build is passing Details
2024-09-13 10:48:45 +07:00
irfan 50ac2d97a4 ci: update Docker file use NPM instead of Yarn
continuous-integration/drone/push Build is passing Details
2024-09-13 03:27:14 +00:00
firmanr d788a9f1a1 Merge pull request 'feat(SPG-953): penyesuaian API Create dan Update pengguna baru dengan menambahkan opsi admin antrian' (#89) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #89
2024-09-12 12:19:09 +00:00
Firman Ramdhani c897e4fcde feat(SPG-885): add validation login admin queue
continuous-integration/drone/push Build is passing Details
2024-09-12 19:17:46 +07:00
Firman Ramdhani 14dd2880bc feat(SPG-885): add api get item queue
continuous-integration/drone/push Build is passing Details
2024-09-12 17:54:48 +07:00
Firman Ramdhani 3e920755bd feat: create feature log user login and create auth admin queue
continuous-integration/drone/push Build is passing Details
2024-09-12 17:16:56 +07:00
Firman Ramdhani 88b4c66139 feat: adjustment column dpp and total pajak at income item master
continuous-integration/drone/push Build is passing Details
2024-09-11 18:15:16 +07:00
Firman Ramdhani 52c82a9a41 feat(SPG-953): penyesuaian API Create dan Update pengguna baru dengan menambahkan opsi admin antrian
continuous-integration/drone/push Build is passing Details
2024-09-11 16:43:03 +07:00
shancheas 19494b3328 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2024-09-11 16:12:36 +07:00
shancheas e1f2cdfa4d wip: calculate share item 2024-09-11 16:12:22 +07:00
firmanr 918055beb9 Merge pull request 'feat: add enum queue admin' (#88) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #88
2024-09-11 07:57:35 +00:00
Firman Ramdhani 283b783007 feat: add enum queue admin
continuous-integration/drone/push Build is passing Details
2024-09-11 14:56:55 +07:00
firmanr a2be2bb331 Merge pull request 'feat/adjustment-report' (#87) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #87
2024-09-11 05:44:29 +00:00
Firman Ramdhani d708ef9eee feat: add column pos name
continuous-integration/drone/push Build is passing Details
2024-09-11 12:42:09 +07:00
Firman Ramdhani 9709c4719b feat: add column pos name
continuous-integration/drone/push Build is passing Details
2024-09-11 12:38:16 +07:00
firmanr d2db62339f Merge pull request 'feat: penyesuaian error validasi create items' (#86) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #86
2024-09-11 04:05:56 +00:00
Firman Ramdhani 07d1cc78e2 feat: penyesuaian error validasi create items
continuous-integration/drone/push Build is passing Details
2024-09-11 11:05:36 +07:00
firmanr 8f430574ed Merge pull request 'feat: rename label button email template midtrans' (#85) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #85
2024-09-11 03:58:36 +00:00
Firman Ramdhani f7198010d3 feat: rename label button email template midtrans
continuous-integration/drone/push Build is passing Details
2024-09-11 10:57:25 +07:00
firmanr a1641504f1 Merge pull request 'feat/adjustment-report' (#84) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #84
2024-09-11 03:52:02 +00:00
Firman Ramdhani 6c5019f814 feat: adjustment dpp and total pajak di report icom per transaction
continuous-integration/drone/push Build is passing Details
2024-09-11 10:51:10 +07:00
Firman Ramdhani ff0ef28783 feat: create report tenant
continuous-integration/drone/push Build is passing Details
2024-09-11 10:40:44 +07:00
firmanr 40aafaf571 Merge pull request 'feat: ignore sync delete data from POS data' (#83) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #83
2024-09-10 10:26:19 +00:00
Firman Ramdhani 6fbb2e33b2 feat: ignore sync delete data from POS data
continuous-integration/drone/push Build is passing Details
2024-09-10 17:25:59 +07:00
firmanr b20385dacc Merge pull request 'feat/adjustment-report' (#82) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is failing Details
Reviewed-on: #82
2024-09-10 10:17:42 +00:00
Firman Ramdhani 6e5b19380b feat(SPG-935): add column payment_date_bank
continuous-integration/drone/push Build is passing Details
2024-09-10 17:15:52 +07:00
Firman Ramdhani ab9ec4ac0e feat(SPG-935): add column payment_date_bank
continuous-integration/drone/push Build is passing Details
2024-09-10 17:11:20 +07:00
firmanr 0457fc9e1d Merge pull request 'feat/adjustment-report' (#81) from feat/adjustment-report into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #81
2024-09-10 04:49:35 +00:00
Firman Ramdhani 3658ae4cdf feat: adjustment filter pos no
continuous-integration/drone/push Build is passing Details
2024-09-10 11:48:44 +07:00
Firman Ramdhani d1b20e6b96 feat: create report tenant
continuous-integration/drone/push Build is passing Details
2024-09-10 11:38:46 +07:00
Firman Ramdhani f4ecbf0e66 feat: add net pedapatan di report rekonsiliasi
continuous-integration/drone/push Build is passing Details
2024-09-10 10:55:13 +07:00
Firman Ramdhani 7da22277f1 feat: remove MDR column on income
continuous-integration/drone/push Build is passing Details
2024-09-10 10:37:48 +07:00
Firman Ramdhani bf73cb6b43 feat: adjustment to measure at column income report
continuous-integration/drone/push Build is passing Details
2024-09-10 10:29:31 +07:00
Firman Ramdhani 6fb582204a Merge branch 'feat/fix-couch-transaction' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/adjustment-report
continuous-integration/drone/push Build is passing Details
2024-09-09 14:30:53 +07:00
Firman Ramdhani d283caa898 feat: rename label header
continuous-integration/drone/push Build is passing Details
2024-09-09 14:26:49 +07:00
Firman Ramdhani 1320492bf1 Merge branch 'production' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/adjustment-report
continuous-integration/drone/push Build is passing Details
2024-09-09 11:26:48 +07:00
firmanr 4c25b2cbec Merge pull request 'feat: open guard cancel recap recon and add new logic for recap recon cancel handler and change logic recap handler' (#79) from feat/reconciliation into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build encountered an error Details
Reviewed-on: #79
2024-09-06 11:42:28 +00:00
irfan a6b1e5f49f Update Dockerfile
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-09-06 11:05:32 +00:00
firmanr ac3ee266b9 Merge pull request 'feat: open guard cancel recap recon and add new logic for recap recon cancel handler and change logic recap handler' (#80) from feat/reconciliation into development
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #80
2024-09-06 10:58:46 +00:00
Firman Ramdhani 3720df31d8 feat: open guard cancel recap recon and add new logic for recap recon cancel handler and change logic recap handler
continuous-integration/drone/push Build is passing Details
2024-09-06 17:57:51 +07:00
Firman Ramdhani 7fb2995f38 feat: update query report income and merge with development branch
continuous-integration/drone/push Build is passing Details
2024-09-04 18:26:40 +07:00
Firman Ramdhani 07e7b86cd4 feat: update query report income and merge with development branch
continuous-integration/drone/push Build is passing Details
2024-09-04 18:21:08 +07:00
Firman Ramdhani db57b1973e Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into feat/fix-couch-transaction 2024-09-04 18:20:13 +07:00
Firman Ramdhani 92d60d4496 feat: update query report income
continuous-integration/drone/push Build is passing Details
2024-09-04 18:19:42 +07:00
firmanr b716c75a2c Merge pull request 'feat/fix-couch-transaction' (#78) from feat/fix-couch-transaction into development
continuous-integration/drone/push Build is passing Details
Reviewed-on: #78
2024-09-04 10:26:33 +00:00
Firman Ramdhani 45306dde57 feat: update import couch module
continuous-integration/drone/push Build is passing Details
2024-09-04 15:22:42 +07:00
irfan 539676aa30 chore: add label to apm
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2024-09-03 11:45:30 +00:00
shancheas 1a2a37d185 chore: add label to APM 2024-09-03 18:44:04 +07:00
irfan 5666c31dfa Merge pull request 'pre-production' (#77) from pre-production into production
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #77
2024-09-03 11:16:58 +00:00
shancheas 665eacd39f feat: add reject QR gate
continuous-integration/drone/tag Build is passing Details
2024-09-03 10:23:02 +07:00
shancheas 9d98003a2d feat: add detail formula api getter
continuous-integration/drone/tag Build is passing Details
2024-09-03 09:45:23 +07:00
shancheas 45c4bde838 feat: add gate scanner module
continuous-integration/drone/tag Build is passing Details
2024-09-02 13:59:19 +07:00
shancheas b9927da0c4 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
continuous-integration/drone/tag Build is passing Details
2024-09-02 13:07:38 +07:00
Firman Ramdhani d523009acd feat: add report income per item master
continuous-integration/drone/tag Build is failing Details
2024-08-30 19:32:03 +07:00
Firman Ramdhani 457ce30cc1 feat: update email template
continuous-integration/drone/tag Build is passing Details
2024-08-30 15:27:24 +07:00
shancheas e7a7ffb2bc feat: add variable config to formula 2024-08-29 17:19:24 +07:00
Firman Ramdhani 2527437577 feat: update validation unique data on payment method module
continuous-integration/drone/tag Build is passing Details
2024-08-29 13:31:24 +07:00
shancheas ce372de1fd fix: remove event when update privilege
continuous-integration/drone/tag Build is passing Details
2024-08-28 19:48:08 +07:00
Supan Adit Pratama 4a13730231 ci: fix production env
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2024-08-23 10:06:24 +07:00
384 changed files with 30964 additions and 544 deletions

View File

@ -2,18 +2,42 @@ kind: pipeline
type: docker type: docker
name: server name: server
steps: steps:
- name: build # - name: build
image: appleboy/drone-ssh # image: appleboy/drone-ssh
# settings:
# host:
# - 172.10.10.10
# username: eigen
# key:
# from_secret: DEVOPS_SSH_PRIVATE_OPEN
# port: 22
# script:
# - cd /home/eigen/PROJECT/POS/POS.DEV/BE
# - sh build.sh
# when:
# ref:
# - refs/tags/devel_*
# - refs/tags/*-alpha.*
- name: build-testing
image: plugins/docker
settings: settings:
host: registry: registry.eigen.co.id
- 172.10.10.10 repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
username: eigen tags: ${DRONE_TAG}
key: custom_dns: 172.10.10.16
from_secret: DEVOPS_SSH_PRIVATE_OPEN when:
port: 22 ref:
script: - refs/tags/*-alpha.*
- cd /home/eigen/PROJECT/POS/POS.DEV/BE - name: build-production
- sh build.sh image: plugins/docker
settings:
registry: registry.eigen.co.id
repo: registry.eigen.co.id/eigen/${DRONE_REPO_NAME}
tags: ${DRONE_TAG}
custom_dns: 172.10.10.16
when:
ref:
- refs/tags/*-production.*
- name: send-message - name: send-message
image: plugins/webhook image: plugins/webhook
settings: settings:
@ -27,9 +51,59 @@ steps:
"message": "Build {{repo.name}} sudah selesai" "message": "Build {{repo.name}} sudah selesai"
} }
trigger: trigger:
ref:
- refs/tags/devel_*
- refs/tags/*-alpha.*
event: event:
exclude: exclude:
- promote - promote
---
kind: pipeline
type: docker
name: kustomize
clone:
disable: true
steps:
- name: kustomize-testing
image: registry.k8s.io/kustomize/kustomize:v5.0.0
environment:
DEVOPS_SSH_PRIVATE:
from_secret: DEVOPS_SSH_PRIVATE
DEVOPS_SSH_PUBLIC:
from_secret: DEVOPS_SSH_PUBLIC
INFRASTRUCTURE_REPO: "k8s-kustomize-external"
DIRECTORY_NAME: "weplay-pos-testing"
commands:
- mkdir -p ~/.ssh &&
- echo $DEVOPS_SSH_PRIVATE | base64 -d > ~/.ssh/id_rsa &&
- echo $DEVOPS_SSH_PUBLIC | base64 -d > ~/.ssh/id_rsa.pub &&
- ssh-keyscan -H -p 2222 git.eigen.co.id >> ~/.ssh/known_hosts &&
- chmod 700 ~/.ssh/ &&
- chmod 600 ~/.ssh/id_rsa &&
- git clone ssh://git@git.eigen.co.id:2222/eigen/$INFRASTRUCTURE_REPO.git &&
- cd $INFRASTRUCTURE_REPO/$DIRECTORY_NAME
- kustomize edit set image registry.eigen.co.id/eigen/$DRONE_REPO_NAME=registry.eigen.co.id/eigen/$DRONE_REPO_NAME:$DRONE_TAG &&
- git add . &&
- |-
git commit -m "feat: update $DRONE_REPO_NAME testing to $DRONE_TAG" &&
- git push origin master
- name: send-message
image: harbor.eigen.co.id/docker.com/plugins/webhook
settings:
urls: https://mattermost.eigen.co.id/api/v4/posts
content_type: application/json
headers:
- Authorization=Bearer 5zubexudb38uuradfa36qy98ca
template: |
{
"channel_id": "s1ekqde1c3du5p35g6budnuotc",
"message": "ALERT: {{ repo.name }} gagal update dengan tag ${DRONE_TAG}"
}
when:
status:
- failure
trigger:
ref:
include:
- refs/tags/*-alpha.*
depends_on:
- server

View File

@ -5,11 +5,11 @@ COPY . .
RUN yarn install RUN yarn install
RUN yarn build RUN yarn build
FROM node:18.17-alpine FROM node:18.17-alpine
ARG env_target # ARG env_target
WORKDIR /app WORKDIR /app
RUN echo ${env_target} # RUN echo ${env_target}
COPY env/$env_target /app/.env # COPY env/$env_target /app/.env
COPY --from=builder /app/env/$env_target .env # COPY --from=builder /app/env/$env_target .env
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist COPY --from=builder /app/dist ./dist
COPY --from=builder /app/assets ./assets COPY --from=builder /app/assets ./assets

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
assets/image/we.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB

5
env/env.development vendored
View File

@ -43,4 +43,7 @@ GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec1
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin SUPERSET_ADMIN_PASSWORD=admin
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV

5
env/env.production vendored
View File

@ -40,4 +40,7 @@ GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec1
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin SUPERSET_ADMIN_PASSWORD=admin
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV

View File

@ -49,6 +49,7 @@
"exceljs": "^4.4.0", "exceljs": "^4.4.0",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"googleapis": "^140.0.0", "googleapis": "^140.0.0",
"gtts": "^0.2.1",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",
"mathjs": "^13.0.2", "mathjs": "^13.0.2",
"midtrans-client": "^1.3.1", "midtrans-client": "^1.3.1",
@ -58,6 +59,7 @@
"pdfmake": "^0.2.10", "pdfmake": "^0.2.10",
"pg": "^8.11.5", "pg": "^8.11.5",
"plop": "^4.0.1", "plop": "^4.0.1",
"qrcode": "^1.5.4",
"reflect-metadata": "^0.2.0", "reflect-metadata": "^0.2.0",
"rxjs": "^7.5.0", "rxjs": "^7.5.0",
"typeorm": "^0.3.20", "typeorm": "^0.3.20",
@ -70,6 +72,7 @@
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/jest": "29.5.12", "@types/jest": "29.5.12",
"@types/node": "^20.12.13", "@types/node": "^20.12.13",
"@types/qrcode": "^1.5.5",
"@types/supertest": "^2.0.11", "@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0", "@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0", "@typescript-eslint/parser": "^5.0.0",

View File

@ -33,7 +33,10 @@ import { SeasonTypeModel } from './modules/season-related/season-type/data/model
import { TaxModule } from './modules/transaction/tax/tax.module'; import { TaxModule } from './modules/transaction/tax/tax.module';
import { TaxModel } from './modules/transaction/tax/data/models/tax.model'; import { TaxModel } from './modules/transaction/tax/data/models/tax.model';
import { SalesPriceFormulaModule } from './modules/transaction/sales-price-formula/sales-price-formula.module'; import { SalesPriceFormulaModule } from './modules/transaction/sales-price-formula/sales-price-formula.module';
import { SalesPriceFormulaModel } from './modules/transaction/sales-price-formula/data/models/sales-price-formula.model'; import {
SalesPriceFormulaModel,
TransactionSettingModel,
} from './modules/transaction/sales-price-formula/data/models/sales-price-formula.model';
import { ProfitShareFormulaModule } from './modules/transaction/profit-share-formula/profit-share-formula.module'; import { ProfitShareFormulaModule } from './modules/transaction/profit-share-formula/profit-share-formula.module';
import { PaymentMethodModule } from './modules/transaction/payment-method/payment-method.module'; import { PaymentMethodModule } from './modules/transaction/payment-method/payment-method.module';
import { PaymentMethodModel } from './modules/transaction/payment-method/data/models/payment-method.model'; import { PaymentMethodModel } from './modules/transaction/payment-method/data/models/payment-method.model';
@ -45,8 +48,10 @@ import { GoogleCalendarModule } from './modules/configuration/google-calendar/go
import { TransactionModule } from './modules/transaction/transaction/transaction.module'; import { TransactionModule } from './modules/transaction/transaction/transaction.module';
import { TransactionModel } from './modules/transaction/transaction/data/models/transaction.model'; import { TransactionModel } from './modules/transaction/transaction/data/models/transaction.model';
import { import {
TransactionBreakdownTaxModel,
TransactionItemBreakdownModel, TransactionItemBreakdownModel,
TransactionItemModel, TransactionItemModel,
TransactionItemTaxModel,
} from './modules/transaction/transaction/data/models/transaction-item.model'; } from './modules/transaction/transaction/data/models/transaction-item.model';
import { TransactionTaxModel } from './modules/transaction/transaction/data/models/transaction-tax.model'; import { TransactionTaxModel } from './modules/transaction/transaction/data/models/transaction-tax.model';
import { ReconciliationModule } from './modules/transaction/reconciliation/reconciliation.module'; import { ReconciliationModule } from './modules/transaction/reconciliation/reconciliation.module';
@ -76,6 +81,32 @@ import { PosLogModel } from './modules/configuration/log/data/models/pos-log.mod
import { ExportModule } from './modules/configuration/export/export.module'; import { ExportModule } from './modules/configuration/export/export.module';
import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model'; import { TransactionDemographyModel } from './modules/transaction/transaction/data/models/transaction-demography.model';
import { SupersetModule } from './modules/configuration/superset/superset.module'; import { SupersetModule } from './modules/configuration/superset/superset.module';
import { GateScanModule } from './modules/gates/gate.module';
import { UserLoginModel } from './modules/user-related/user/data/models/user-login.model';
import { LogUserLoginModel } from './modules/configuration/log/data/models/log-user-login.model';
import { AuthService } from './core/guards/domain/services/auth.service';
import { ReportSummaryModule } from './modules/reports/report-summary/report-summary.module';
import { QueueModule } from './modules/queue/queue.module';
import {
QueueOrderModel,
QueueTicketModel,
QueueItemModel,
QueueModel,
} from './modules/queue/data/models/queue.model';
import { ItemQueueModule } from './modules/item-related/item-queue/item-queue.module';
import { ItemQueueModel } from './modules/item-related/item-queue/data/models/item-queue.model';
import { QueueBucketModel } from './modules/queue/data/models/queue-bucket.model';
import { VerificationModel } from './modules/booking-online/authentication/data/models/verification.model';
import { BookingOnlineAuthModule } from './modules/booking-online/authentication/auth.module';
import { BookingOrderModule } from './modules/booking-online/order/order.module';
import { TimeGroupModule } from './modules/item-related/time-group/time-group.module';
import { TimeGroupModel } from './modules/item-related/time-group/data/models/time-group.model';
import { OtpVerificationModule } from './modules/configuration/otp-verification/otp-verification.module';
import { OtpVerificationModel } from './modules/configuration/otp-verification/data/models/otp-verification.model';
import { OtpVerifierModel } from './modules/configuration/otp-verification/data/models/otp-verifier.model';
import { RescheduleVerificationModel } from './modules/booking-online/order/data/models/reschedule-verification.model';
import { OtpCheckerGuard } from './core/guards/domain/otp-checker.guard';
@Module({ @Module({
imports: [ imports: [
@ -100,7 +131,10 @@ import { SupersetModule } from './modules/configuration/superset/superset.module
ItemModel, ItemModel,
ItemCategoryModel, ItemCategoryModel,
ItemRateModel, ItemRateModel,
ItemQueueModel,
TimeGroupModel,
LogModel, LogModel,
LogUserLoginModel,
NewsModel, NewsModel,
PaymentMethodModel, PaymentMethodModel,
PosLogModel, PosLogModel,
@ -116,13 +150,32 @@ import { SupersetModule } from './modules/configuration/superset/superset.module
TransactionTaxModel, TransactionTaxModel,
TransactionDemographyModel, TransactionDemographyModel,
TransactionItemBreakdownModel, TransactionItemBreakdownModel,
TransactionItemTaxModel,
TransactionBreakdownTaxModel,
TransactionSettingModel,
UserModel, UserModel,
UserLoginModel,
VipCategoryModel, VipCategoryModel,
VipCodeModel, VipCodeModel,
// report // report
ReportBookmarkModel, ReportBookmarkModel,
ExportReportHistoryModel, ExportReportHistoryModel,
// Queue
QueueOrderModel,
QueueTicketModel,
QueueItemModel,
QueueModel,
QueueBucketModel,
// Booking Online
VerificationModel,
RescheduleVerificationModel,
OtpVerificationModel,
OtpVerifierModel,
], ],
synchronize: false, synchronize: false,
}), }),
@ -148,6 +201,8 @@ import { SupersetModule } from './modules/configuration/superset/superset.module
ItemCategoryModule, ItemCategoryModule,
ItemModule, ItemModule,
ItemRateModule, ItemRateModule,
ItemQueueModule,
TimeGroupModule,
// transaction // transaction
PaymentMethodModule, PaymentMethodModule,
@ -175,13 +230,25 @@ import { SupersetModule } from './modules/configuration/superset/superset.module
ReportModule, ReportModule,
ReportBookmarkModule, ReportBookmarkModule,
ReportExportModule, ReportExportModule,
ReportSummaryModule,
// superset // superset
SupersetModule, SupersetModule,
GateScanModule,
QueueModule,
BookingOnlineAuthModule,
BookingOrderModule,
OtpVerificationModule,
], ],
controllers: [], controllers: [],
providers: [ providers: [
AuthService,
PrivilegeService, PrivilegeService,
OtpCheckerGuard,
/** /**
* By default all request from client will protect by JWT * By default all request from client will protect by JWT
* if there is some endpoint/function that does'nt require authentication * if there is some endpoint/function that does'nt require authentication

View File

@ -7,10 +7,10 @@ import {
UnauthorizedException, UnauthorizedException,
} from '@nestjs/common'; } from '@nestjs/common';
import { Reflector } from '@nestjs/core'; import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { SessionService, UsersSession } from 'src/core/sessions'; import { SessionService, UsersSession } from 'src/core/sessions';
import { UNPROTECTED_URL } from '../constants'; import { UNPROTECTED_URL } from '../constants';
import { PrivilegeService } from './services/privilege.service'; import { PrivilegeService } from './services/privilege.service';
import { AuthService } from './services/auth.service';
@Injectable({ scope: Scope.REQUEST }) @Injectable({ scope: Scope.REQUEST })
export class JWTGuard implements CanActivate { export class JWTGuard implements CanActivate {
@ -18,14 +18,13 @@ export class JWTGuard implements CanActivate {
protected readonly session: SessionService, protected readonly session: SessionService,
protected readonly reflector: Reflector, protected readonly reflector: Reflector,
protected readonly privilege: PrivilegeService, protected readonly privilege: PrivilegeService,
protected readonly authService: AuthService,
) {} ) {}
protected isPublic = false; protected isPublic = false;
protected userSession: UsersSession; protected userSession: UsersSession;
canActivate( async canActivate(context: ExecutionContext) {
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
/** /**
* Check if access url is protected or not * Check if access url is protected or not
* By default `isUnprotected` equals `false` * By default `isUnprotected` equals `false`
@ -61,9 +60,29 @@ export class JWTGuard implements CanActivate {
*/ */
try { try {
this.userSession = this.session.verifyToken(token); this.userSession = this.session.verifyToken(token);
await this.authService.verifyRegisteredLoginToken(token);
Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard'); Logger.log(`Access from ${this.userSession.name}`, 'AuthGuard');
return true; return true;
} catch (error) { } catch (error) {
const expiredError = error.message;
if (expiredError === 'jwt expired') {
const [, body] = token.split('.');
const bodyToken = JSON.parse(atob(body));
const user = {
role: bodyToken.role,
user_id: bodyToken.id,
username: bodyToken.username,
user_privilege_id: bodyToken.user_privilege_id,
item_id: bodyToken.item_id,
item_name: bodyToken.item_name,
source: bodyToken.source,
};
this.authService.logoutUser(user, token);
}
throw new UnauthorizedException({ throw new UnauthorizedException({
code: 10001, code: 10001,
message: message:

View File

@ -0,0 +1,57 @@
import {
CanActivate,
ExecutionContext,
Injectable,
UnprocessableEntityException,
} from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { OtpVerificationModel } from 'src/modules/configuration/otp-verification/data/models/otp-verification.model';
import { OtpVerificationEntity } from 'src/modules/configuration/otp-verification/domain/entities/otp-verification.entity';
import { DataSource } from 'typeorm';
@Injectable()
export class OtpCheckerGuard implements CanActivate {
constructor(
@InjectDataSource(CONNECTION_NAME.DEFAULT)
protected readonly dataSource: DataSource,
) {}
get otpRepository() {
return this.dataSource.getRepository(OtpVerificationModel);
}
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const verificationCode = request.headers['x-verification-code'];
console.log({ verificationCode });
if (verificationCode) {
const decoded = Buffer.from(verificationCode, 'base64').toString('ascii');
const [dataIdentity, otpCode] = decoded.split('|');
let otpData: OtpVerificationEntity;
otpData = await this.otpRepository.findOne({
where: {
otp_code: otpCode,
target_id: dataIdentity,
},
});
if (!otpData) {
otpData = await this.otpRepository.findOne({
where: {
otp_code: otpCode,
reference: dataIdentity,
},
});
}
// console.log({ dataIdentity, otpCode, otpData });
if (otpData && otpData?.verified_at) return true;
}
throw new UnprocessableEntityException('OTP not verified.');
}
}

View File

@ -9,7 +9,7 @@ import { MAIN_MENU } from '../constants';
@Injectable() @Injectable()
export class RolesGuard extends JWTGuard { export class RolesGuard extends JWTGuard {
async canActivate(context: ExecutionContext): Promise<boolean> { async canActivate(context: ExecutionContext): Promise<boolean> {
super.canActivate(context); await super.canActivate(context);
// jika endpoint tersebut bukan public, maka lakukan check lanjutan // jika endpoint tersebut bukan public, maka lakukan check lanjutan
if (!this.isPublic) { if (!this.isPublic) {

View File

@ -0,0 +1,78 @@
import {
HttpStatus,
Injectable,
Scope,
UnauthorizedException,
} from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import {
CONNECTION_NAME,
OPERATION,
} from 'src/core/strings/constants/base.constants';
import { DataSource } from 'typeorm';
import { UserRole } from 'src/modules/user-related/user/constants';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { AppSource, LogUserType } from 'src/core/helpers/constant';
import { EventBus } from '@nestjs/cqrs';
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
import { UserLoginModel } from 'src/modules/user-related/user/data/models/user-login.model';
interface UserEntity {
user_id: string;
username: string;
role: UserRole;
user_privilege_id: string;
item_id: string;
item_name: string;
source: AppSource;
}
@Injectable({ scope: Scope.REQUEST })
export class AuthService {
constructor(
@InjectDataSource(CONNECTION_NAME.DEFAULT)
protected readonly dataSource: DataSource,
private eventBus: EventBus,
) {}
get repository() {
return this.dataSource.getRepository(UserLoginModel);
}
async logoutUser(user: UserEntity, token: string) {
await this.repository.delete({ login_token: token });
const userLogout = {
type: LogUserType.logout,
created_at: new Date().getTime(),
name: user.username,
user_privilege_id: user.user_privilege_id,
...user,
};
this.eventBus.publish(
new LogUserLoginEvent({
id: user.user_id,
old: null,
data: userLogout,
user: userLogout as any,
description: 'Logout',
module: UserModel.name,
op: OPERATION.UPDATE,
}),
);
}
async verifyRegisteredLoginToken(token: string) {
const data = await this.repository.findOneBy({ login_token: token });
if (!data) {
throw new UnauthorizedException({
statusCode: HttpStatus.UNAUTHORIZED,
message: `Invalid token`,
error: 'Unauthorized',
});
}
}
}

View File

@ -0,0 +1,11 @@
export enum LogUserType {
login = 'login',
logout = 'logout',
}
export enum AppSource {
POS_ADMIN = 'POS_ADMIN',
POS_COUNTER = 'POS_COUNTER',
QUEUE_ADMIN = 'QUEUE_ADMIN',
QUEUE_CUSTOMER = 'QUEUE_CUSTOMER',
}

View File

@ -0,0 +1,66 @@
interface OtpServiceEntity {
length?: number;
}
export class OtpService {
private readonly otpLength: number;
constructor({ length = 4 }: OtpServiceEntity) {
this.otpLength = Math.max(length, 4); // Minimum of 4 digits
}
private hasSequentialDigits(str: string): boolean {
for (let i = 0; i < str.length - 1; i++) {
const current = parseInt(str[i], 10);
const next = parseInt(str[i + 1], 10);
if (next === current + 1 || next === current - 1) {
return true;
}
}
return false;
}
private hasRepeatedDigits(str: string): boolean {
return str.split('').every((char) => char === str[0]);
}
private isPalindrome(str: string): boolean {
return str === str.split('').reverse().join('');
}
private hasPartiallyRepeatedDigits(str: string): boolean {
const counts: Record<string, number> = {};
for (const char of str) {
counts[char] = (counts[char] || 0) + 1;
}
// Reject if any digit appears more than twice
return Object.values(counts).some((count) => count > 2);
}
private hasNoMatchLength(str: string) {
return str.length !== this.otpLength;
}
private hasStartWithZero(str: string) {
return str.split('')[0] === '0';
}
public generateSecureOTP(): string {
let otp: string;
do {
otp = Array.from({ length: this.otpLength }, () =>
Math.floor(Math.random() * 10).toString(),
).join('');
} while (
this.hasNoMatchLength(otp) ||
this.hasSequentialDigits(otp) ||
this.hasRepeatedDigits(otp) ||
this.isPalindrome(otp) ||
this.hasPartiallyRepeatedDigits(otp) ||
this.hasStartWithZero(otp)
);
return otp;
}
}

View File

@ -8,7 +8,9 @@ import { diskStorage } from 'multer';
const MB = 1024 * 1024; const MB = 1024 * 1024;
const fileFilter = (req, file, callback) => { const fileFilter = (req, file, callback) => {
if (file.mimetype.match(/\/(jpg|jpeg|png)$/)) { if (
file.mimetype.match(/\/(jpg|jpeg|png|flv|mp4|m3u8|ts|3gp|mov|avi|wmv)$/)
) {
callback(null, true); callback(null, true);
} else { } else {
callback( callback(

View File

@ -55,7 +55,7 @@ export class ValidateRelationHelper<Entity> {
const relationColumn = const relationColumn =
data[relation.relation]?.[`${relation.singleQuery[0]}`]; data[relation.relation]?.[`${relation.singleQuery[0]}`];
if ( if (
!!relationColumn && // !!relationColumn &&
this.mappingValidator( this.mappingValidator(
relationColumn, relationColumn,
relation.singleQuery[1], relation.singleQuery[1],

View File

@ -32,7 +32,7 @@ export abstract class BaseManager {
setUser() { setUser() {
try { try {
this.user = this.userProvider?.user; this.user = this.userProvider?.user ?? BLANK_USER;
} catch (error) { } catch (error) {
this.user = BLANK_USER; this.user = BLANK_USER;
} }

View File

@ -71,7 +71,7 @@ export abstract class BaseCreateManager<Entity> extends BaseManager {
} }
async publishEvents() { async publishEvents() {
this.eventBus.publish( this.eventBus?.publish(
new RecordLog({ new RecordLog({
id: this.result['id'], id: this.result['id'],
old: null, old: null,

View File

@ -50,7 +50,7 @@ export abstract class BaseIndexManager<Entity> extends BaseReadManager {
// jika searching status terdapat dalam enum, maka dia mencari specific data // jika searching status terdapat dalam enum, maka dia mencari specific data
// ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut // ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut
return `'${STATUS[statusData.toUpperCase()]}'` ?? `'%${statusData}%'`; return `'${STATUS[statusData.toUpperCase()]}'`;
}); });
const exist = specificFilter.find((item) => item.isStatus); const exist = specificFilter.find((item) => item.isStatus);

View File

@ -1,6 +1,10 @@
import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper'; import { ValidateRelationHelper } from 'src/core/helpers/validation/validate-relation.helper';
import { BaseManager } from '../base.manager'; import { BaseManager } from '../base.manager';
import { OPERATION, STATUS } from 'src/core/strings/constants/base.constants'; import {
OPERATION,
QUEUE_STATUS,
STATUS,
} from 'src/core/strings/constants/base.constants';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event'; import { RecordLog } from 'src/modules/configuration/log/domain/entities/log.event';
@ -8,12 +12,12 @@ export abstract class BaseUpdateStatusManager<Entity> extends BaseManager {
protected dataId: string; protected dataId: string;
protected result: Entity; protected result: Entity;
protected oldData: Entity; protected oldData: Entity;
protected dataStatus: STATUS; protected dataStatus: STATUS | QUEUE_STATUS;
protected relations = []; protected relations = [];
protected duplicateColumn: string[]; protected duplicateColumn: string[];
abstract get entityTarget(): any; abstract get entityTarget(): any;
setData(id: string, status: STATUS): void { setData(id: string, status: STATUS | QUEUE_STATUS): void {
/** /**
* // TODO: Handle case confirm multiple tabs; * // TODO: Handle case confirm multiple tabs;
* Pola id yang dikirim dirubah menjadi data_id___updated_at * Pola id yang dikirim dirubah menjadi data_id___updated_at

View File

@ -23,6 +23,7 @@ export class BaseFilterDto implements BaseFilterEntity {
@IsNumber() @IsNumber()
limit = 10; limit = 10;
@ApiProperty({ type: String, required: false })
q: string; q: string;
@ApiProperty({ type: ['string'], required: false }) @ApiProperty({ type: ['string'], required: false })

View File

@ -1 +1,2 @@
export const PAGINATION_RESPONSE = 'PAGINATION_RESPONSE'; export const PAGINATION_RESPONSE = 'PAGINATION_RESPONSE';
export const GATE_RESPONSE = 'GATE_RESPONSE';

View File

@ -1,5 +1,5 @@
import { SetMetadata } from '@nestjs/common'; import { SetMetadata } from '@nestjs/common';
import { PAGINATION_RESPONSE } from '../../constants'; import { GATE_RESPONSE, PAGINATION_RESPONSE } from '../../constants';
/** /**
* This decorator will tell the response, * This decorator will tell the response,
@ -7,3 +7,5 @@ import { PAGINATION_RESPONSE } from '../../constants';
*/ */
export const Pagination = (isPagination = true) => export const Pagination = (isPagination = true) =>
SetMetadata(PAGINATION_RESPONSE, isPagination); SetMetadata(PAGINATION_RESPONSE, isPagination);
export const Gate = () => SetMetadata(GATE_RESPONSE, true);

View File

@ -8,13 +8,20 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { Request } from 'express'; import { Request } from 'express';
import { Reflector } from '@nestjs/core'; import { Reflector } from '@nestjs/core';
import { PAGINATION_RESPONSE } from '../constants'; import { GATE_RESPONSE, PAGINATION_RESPONSE } from '../constants';
import { createPaginationResponse } from './utils/pagination-meta.helper'; import { createPaginationResponse } from './utils/pagination-meta.helper';
@Injectable() @Injectable()
export class TransformInterceptor implements NestInterceptor { export class TransformInterceptor implements NestInterceptor {
constructor(protected readonly reflector: Reflector) {} constructor(protected readonly reflector: Reflector) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> { intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const isGate = this.reflector.getAllAndOverride<boolean>(GATE_RESPONSE, [
context.getHandler(),
context.getClass(),
]);
if (isGate) return next.handle();
const isPagination = this.reflector.getAllAndOverride<boolean>( const isPagination = this.reflector.getAllAndOverride<boolean>(
PAGINATION_RESPONSE, PAGINATION_RESPONSE,
[context.getHandler(), context.getClass()], [context.getHandler(), context.getClass()],

View File

@ -1,8 +1,11 @@
import { AppSource } from 'src/core/helpers/constant';
import { UserRole } from 'src/modules/user-related/user/constants'; import { UserRole } from 'src/modules/user-related/user/constants';
export interface UsersSession { export interface UsersSession {
id: number; id: number;
name: string; name: string;
role: UserRole; role: UserRole;
source?: AppSource;
item_id?: string;
user_privilege_id: string; user_privilege_id: string;
} }

View File

@ -23,4 +23,9 @@ export class UserProvider {
const [, token] = this.request.headers['authorization'].split(' '); const [, token] = this.request.headers['authorization'].split(' ');
return this.session.verifyToken(token); return this.session.verifyToken(token);
} }
get token(): string {
const [, token] = this.request.headers['authorization'].split(' ');
return token;
}
} }

View File

@ -15,6 +15,11 @@ export enum STATUS {
WAITING = 'waiting', WAITING = 'waiting',
} }
export enum QUEUE_STATUS {
DONE = 'done',
CALLED = 'called',
}
export enum ORDER_TYPE { export enum ORDER_TYPE {
ASC = 'ASC', ASC = 'ASC',
DESC = 'DESC', DESC = 'DESC',

View File

@ -4,6 +4,7 @@ export enum MODULE_NAME {
GATE = 'gates', GATE = 'gates',
ITEM = 'items', ITEM = 'items',
ITEM_CATEGORY = 'item-categories', ITEM_CATEGORY = 'item-categories',
ITEM_QUEUE = 'item-queues',
ITEM_RATE = 'item-rates', ITEM_RATE = 'item-rates',
NEWS = 'news', NEWS = 'news',
PAYMENT_METHOD = 'payment-methods', PAYMENT_METHOD = 'payment-methods',
@ -24,4 +25,12 @@ export enum MODULE_NAME {
REPORT = 'report', REPORT = 'report',
REPORT_BOOKMARK = 'report-bookmark', REPORT_BOOKMARK = 'report-bookmark',
REPORT_EXPORT = 'report-export', REPORT_EXPORT = 'report-export',
REPORT_SUMMARY = 'report-summary',
QUEUE = 'queue',
TIME_GROUPS = 'time-groups',
OTP_VERIFICATIONS = 'otp-verification',
OTP_VERIFIER = 'otp-verifier',
} }

View File

@ -4,6 +4,7 @@ export enum TABLE_NAME {
FAQ = 'faqs', FAQ = 'faqs',
ITEM = 'items', ITEM = 'items',
ITEM_CATEGORY = 'item_categories', ITEM_CATEGORY = 'item_categories',
ITEM_QUEUE = 'item_queues',
ITEM_RATE = 'item_rates', ITEM_RATE = 'item_rates',
GATE = 'gates', GATE = 'gates',
LOG = 'logs', LOG = 'logs',
@ -11,6 +12,7 @@ export enum TABLE_NAME {
NEWS = 'news', NEWS = 'news',
PAYMENT_METHOD = 'payment_methods', PAYMENT_METHOD = 'payment_methods',
PRICE_FORMULA = 'price_formulas', PRICE_FORMULA = 'price_formulas',
TRANSACTION_SETTING = 'transaction_settings',
REFUND = 'refunds', REFUND = 'refunds',
REFUND_ITEM = 'refund_items', REFUND_ITEM = 'refund_items',
SEASON_TYPE = 'season_types', SEASON_TYPE = 'season_types',
@ -22,8 +24,12 @@ export enum TABLE_NAME {
TRANSACTION_ITEM = 'transaction_items', TRANSACTION_ITEM = 'transaction_items',
TRANSACTION_ITEM_BREAKDOWN = 'transaction_item_breakdowns', TRANSACTION_ITEM_BREAKDOWN = 'transaction_item_breakdowns',
TRANSACTION_TAX = 'transaction_taxes', TRANSACTION_TAX = 'transaction_taxes',
TRANSACTION_ITEM_TAX = 'transaction_item_taxes',
TRANSACTION_ITEM_BREAKDOWN_TAX = 't_breakdown_item_taxes',
TRANSACTION_DEMOGRAPHY = 'transaction_demographies', TRANSACTION_DEMOGRAPHY = 'transaction_demographies',
USER = 'users', USER = 'users',
USER_LOGIN = 'users_login',
LOG_USER_LOGIN = 'log_users_login',
USER_PRIVILEGE = 'user_privileges', USER_PRIVILEGE = 'user_privileges',
USER_PRIVILEGE_CONFIGURATION = 'user_privilege_configurations', USER_PRIVILEGE_CONFIGURATION = 'user_privilege_configurations',
VIP_CATEGORY = 'vip_categories', VIP_CATEGORY = 'vip_categories',
@ -31,4 +37,14 @@ export enum TABLE_NAME {
REPORT_BOOKMARK = 'report_bookmark', REPORT_BOOKMARK = 'report_bookmark',
EXPORT_REPORT_HISTORY = 'export_report_history', EXPORT_REPORT_HISTORY = 'export_report_history',
QUEUE = 'queues',
QUEUE_ORDER = 'queue_orders',
QUEUE_TICKET = 'queue_tickets',
QUEUE_ITEM = 'queue_items',
QUEUE_BUCKET = 'queue_bucket',
TIME_GROUPS = 'time_groups',
OTP_VERIFICATIONS = 'otp_verifications',
OTP_VERIFIER = 'otp_verifier',
} }

View File

@ -5,7 +5,7 @@ export class AddEstimationToItem1723801180604 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query( await queryRunner.query(
`ALTER TABLE "items" ADD "play_estimation" integer`, `ALTER TABLE "items" ADD "play_estimation" numeric`,
); );
} }

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddValueVariableFormula1724926316235
implements MigrationInterface
{
name = 'AddValueVariableFormula1724926316235';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "price_formulas" ADD "value_for" character varying NOT NULL DEFAULT 'dpp'`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "price_formulas" DROP COLUMN "value_for"`,
);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddPaymentDateBankColumnAtTransaction1725962197762
implements MigrationInterface
{
name = 'AddPaymentDateBankColumnAtTransaction1725962197762';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" ADD "payment_date_bank" date`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "payment_date_bank"`,
);
}
}

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddPosNameColumn1726033041774 implements MigrationInterface {
name = 'AddPosNameColumn1726033041774';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" ADD "creator_counter_name" character varying`,
);
await queryRunner.query(
`ALTER TABLE "logs_pos" ADD "pos_name" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "logs_pos" DROP COLUMN "pos_name"`);
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "creator_counter_name"`,
);
}
}

View File

@ -0,0 +1,43 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddFlagRoleQueue1726041175749 implements MigrationInterface {
name = 'AddFlagRoleQueue1726041175749';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TYPE "public"."users_role_enum" RENAME TO "users_role_enum_old"`,
);
await queryRunner.query(
`CREATE TYPE "public"."users_role_enum" AS ENUM('superadmin', 'staff', 'tenant', 'queue_admin')`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" DROP DEFAULT`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" TYPE "public"."users_role_enum" USING "role"::"text"::"public"."users_role_enum"`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" SET DEFAULT 'staff'`,
);
await queryRunner.query(`DROP TYPE "public"."users_role_enum_old"`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."users_role_enum_old" AS ENUM('superadmin', 'staff', 'tenant')`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" DROP DEFAULT`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" TYPE "public"."users_role_enum_old" USING "role"::"text"::"public"."users_role_enum_old"`,
);
await queryRunner.query(
`ALTER TABLE "users" ALTER COLUMN "role" SET DEFAULT 'staff'`,
);
await queryRunner.query(`DROP TYPE "public"."users_role_enum"`);
await queryRunner.query(
`ALTER TYPE "public"."users_role_enum_old" RENAME TO "users_role_enum"`,
);
}
}

View File

@ -0,0 +1,73 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTaxItemTransaction1726045820711 implements MigrationInterface {
name = 'AddTaxItemTransaction1726045820711';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "transaction_item_taxes" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "tax_id" character varying, "tax_name" character varying, "taxt_value" numeric, "tax_total_value" numeric, "transaction_id" uuid, CONSTRAINT "PK_fc5f6da61b24eb5bfdd503b0a0d" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "t_breakdown_item_taxes" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "tax_id" character varying, "tax_name" character varying, "taxt_value" numeric, "tax_total_value" numeric, "transaction_id" uuid, CONSTRAINT "PK_a1ef08d2c68169a50102aa70eca" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "total_profit_share" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "total_profit_share" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_taxes" ADD CONSTRAINT "FK_f5c4966a381d903899cafb4b5ba" FOREIGN KEY ("transaction_id") REFERENCES "transaction_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "t_breakdown_item_taxes" ADD CONSTRAINT "FK_74bedce7e94f6707ddf26ef0c0f" FOREIGN KEY ("transaction_id") REFERENCES "transaction_item_breakdowns"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "payment_total_dpp" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "payment_total_dpp" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "payment_total_tax" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "payment_total_tax" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "total_share_tenant" numeric`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "t_breakdown_item_taxes" DROP CONSTRAINT "FK_74bedce7e94f6707ddf26ef0c0f"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_taxes" DROP CONSTRAINT "FK_f5c4966a381d903899cafb4b5ba"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "total_profit_share"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "total_profit_share"`,
);
await queryRunner.query(`DROP TABLE "t_breakdown_item_taxes"`);
await queryRunner.query(`DROP TABLE "transaction_item_taxes"`);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "payment_total_dpp"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "payment_total_dpp"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "payment_total_tax"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "payment_total_tax"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "total_share_tenant"`,
);
}
}

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTableUserLogin1726115025759 implements MigrationInterface {
name = 'AddTableUserLogin1726115025759';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "users_login" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "login_date" bigint NOT NULL, "login_token" character varying, "user_id" uuid, CONSTRAINT "REL_2a80a213b51423ce5b8211f058" UNIQUE ("user_id"), CONSTRAINT "PK_e564194a9a22f8c623354284f75" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
);
await queryRunner.query(`DROP TABLE "users_login"`);
}
}

View File

@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class UpdateTableUserLogin1726122619596 implements MigrationInterface {
name = 'UpdateTableUserLogin1726122619596';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
}
}

View File

@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTableLogUserLogin1726123955427 implements MigrationInterface {
name = 'AddTableLogUserLogin1726123955427';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."log_users_login_type_enum" AS ENUM('login', 'logout')`,
);
await queryRunner.query(
`CREATE TYPE "public"."log_users_login_role_enum" AS ENUM('superadmin', 'staff', 'tenant', 'queue_admin')`,
);
await queryRunner.query(
`CREATE TABLE "log_users_login" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" "public"."log_users_login_type_enum", "role" "public"."log_users_login_role_enum", "user_id" uuid, "username" character varying, "created_at" bigint, CONSTRAINT "PK_75141588aa6ee560504f7d3adce" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "log_users_login"`);
await queryRunner.query(`DROP TYPE "public"."log_users_login_role_enum"`);
await queryRunner.query(`DROP TYPE "public"."log_users_login_type_enum"`);
}
}

View File

@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddColumnItemId1726139426994 implements MigrationInterface {
name = 'AddColumnItemId1726139426994';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users_login" ADD "item_id" uuid`);
await queryRunner.query(`ALTER TABLE "log_users_login" ADD "item_id" uuid`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "log_users_login" DROP COLUMN "item_id"`,
);
await queryRunner.query(`ALTER TABLE "users_login" DROP COLUMN "item_id"`);
}
}

View File

@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddColumnItemName1726141393404 implements MigrationInterface {
name = 'AddColumnItemName1726141393404';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users_login" ADD "item_name" character varying`,
);
await queryRunner.query(
`ALTER TABLE "log_users_login" ADD "item_name" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "log_users_login" DROP COLUMN "item_name"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" DROP COLUMN "item_name"`,
);
}
}

View File

@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddFormulaToTax1726365023179 implements MigrationInterface {
name = 'AddFormulaToTax1726365023179';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "taxes" ADD "formula_render" json`);
await queryRunner.query(
`ALTER TABLE "taxes" ADD "formula_string" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "taxes" DROP COLUMN "formula_string"`);
await queryRunner.query(`ALTER TABLE "taxes" DROP COLUMN "formula_render"`);
}
}

View File

@ -0,0 +1,35 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ChangeUserLoginRelation1726642119207
implements MigrationInterface
{
name = 'ChangeUserLoginRelation1726642119207';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "refresh_token"`);
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "REL_2a80a213b51423ce5b8211f058"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "users_login" DROP CONSTRAINT "FK_2a80a213b51423ce5b8211f0584"`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "REL_2a80a213b51423ce5b8211f058" UNIQUE ("user_id")`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD CONSTRAINT "FK_2a80a213b51423ce5b8211f0584" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "users" ADD "refresh_token" character varying`,
);
}
}

View File

@ -0,0 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddColumnSourceAtUserLogin1726642499135
implements MigrationInterface
{
name = 'AddColumnSourceAtUserLogin1726642499135';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."users_login_role_enum" AS ENUM('superadmin', 'staff', 'tenant', 'queue_admin')`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD "role" "public"."users_login_role_enum"`,
);
await queryRunner.query(
`CREATE TYPE "public"."users_login_source_enum" AS ENUM('POS_ADMIN', 'POS_COUNTER', 'QUEUE_ADMIN', 'QUEUE_CUSTOMER')`,
);
await queryRunner.query(
`ALTER TABLE "users_login" ADD "source" "public"."users_login_source_enum"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "users_login" DROP COLUMN "source"`);
await queryRunner.query(`DROP TYPE "public"."users_login_source_enum"`);
await queryRunner.query(`ALTER TABLE "users_login" DROP COLUMN "role"`);
await queryRunner.query(`DROP TYPE "public"."users_login_role_enum"`);
}
}

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddSourceOnLogLogin1726647442006 implements MigrationInterface {
name = 'AddSourceOnLogLogin1726647442006';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."log_users_login_source_enum" AS ENUM('POS_ADMIN', 'POS_COUNTER', 'QUEUE_ADMIN', 'QUEUE_CUSTOMER')`,
);
await queryRunner.query(
`ALTER TABLE "log_users_login" ADD "source" "public"."log_users_login_source_enum"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "log_users_login" DROP COLUMN "source"`,
);
await queryRunner.query(`DROP TYPE "public"."log_users_login_source_enum"`);
}
}

View File

@ -0,0 +1,43 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddDiscountForItemTransaction1726824289989
implements MigrationInterface
{
name = 'AddDiscountForItemTransaction1726824289989';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "subtotal" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "discount_value" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "subtotal" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "discount_value" numeric`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" ADD "total_price" numeric`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "total_price"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "discount_value"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" DROP COLUMN "subtotal"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "discount_value"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "subtotal"`,
);
}
}

View File

@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ChangeColumnName1726830293878 implements MigrationInterface {
name = 'ChangeColumnName1726830293878';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_items" RENAME COLUMN "subtotal" TO "total_net_price"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" RENAME COLUMN "subtotal" TO "total_net_price"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_item_breakdowns" RENAME COLUMN "total_net_price" TO "subtotal"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" RENAME COLUMN "total_net_price" TO "subtotal"`,
);
}
}

View File

@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddDiscountValueToVoucher1728377112337
implements MigrationInterface
{
name = 'AddDiscountValueToVoucher1728377112337';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "vip_codes" ADD "discount_value" numeric`,
);
await queryRunner.query(
`ALTER TABLE "vip_codes" ALTER COLUMN "discount" DROP NOT NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "vip_codes" ALTER COLUMN "discount" SET NOT NULL`,
);
await queryRunner.query(
`ALTER TABLE "vip_codes" DROP COLUMN "discount_value"`,
);
}
}

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ItemVideoAndVipPass1729072422409 implements MigrationInterface {
name = 'ItemVideoAndVipPass1729072422409';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" ADD "video_url" character varying`,
);
await queryRunner.query(
`ALTER TABLE "vip_categories" ADD "has_vip_pass" boolean NOT NULL DEFAULT false`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "vip_categories" DROP COLUMN "has_vip_pass"`,
);
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "video_url"`);
}
}

View File

@ -0,0 +1,43 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class QueueTable1729151429165 implements MigrationInterface {
name = 'QueueTable1729151429165';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "queue_orders" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "code" character varying NOT NULL, "customer" character varying, "phone" character varying, "date" bigint NOT NULL, CONSTRAINT "PK_b139e4cc9ca3e709c152f820d2e" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "queue_tickets" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "code" character varying NOT NULL, "customer" character varying, "phone" character varying, "date" bigint NOT NULL, "order_id" uuid, CONSTRAINT "PK_1b903aa90bcc04136caa6540c55" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE TABLE "queue_items" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "qty" integer NOT NULL, "ticket_id" uuid, "item_id" uuid, CONSTRAINT "PK_2245e11ac3517494bacfe932773" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "queue_tickets" ADD CONSTRAINT "FK_0e9823b8b7ca9523b3be73878e5" FOREIGN KEY ("order_id") REFERENCES "queue_orders"("id") ON DELETE SET NULL ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "queue_items" ADD CONSTRAINT "FK_25352739034765f6917757df74b" FOREIGN KEY ("ticket_id") REFERENCES "queue_tickets"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "queue_items" ADD CONSTRAINT "FK_ab15c053aeb4f739ebf533b61cd" FOREIGN KEY ("item_id") REFERENCES "items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queue_items" DROP CONSTRAINT "FK_ab15c053aeb4f739ebf533b61cd"`,
);
await queryRunner.query(
`ALTER TABLE "queue_items" DROP CONSTRAINT "FK_25352739034765f6917757df74b"`,
);
await queryRunner.query(
`ALTER TABLE "queue_tickets" DROP CONSTRAINT "FK_0e9823b8b7ca9523b3be73878e5"`,
);
await queryRunner.query(`DROP TABLE "queue_items"`);
await queryRunner.query(`DROP TABLE "queue_tickets"`);
await queryRunner.query(`DROP TABLE "queue_orders"`);
}
}

View File

@ -0,0 +1,18 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class VideoUrlToJson1729248576381 implements MigrationInterface {
name = 'VideoUrlToJson1729248576381';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "video_url"`);
await queryRunner.query(`ALTER TABLE "items" ADD "video_url" json`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "video_url"`);
await queryRunner.query(
`ALTER TABLE "items" ADD "video_url" character varying`,
);
await queryRunner.query(`DROP TABLE "item_queues"`);
}
}

View File

@ -0,0 +1,33 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ItemQueues1729570177597 implements MigrationInterface {
name = 'ItemQueues1729570177597';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."item_queues_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
);
await queryRunner.query(
`CREATE TYPE "public"."item_queues_item_type_enum" AS ENUM('tiket masuk', 'wahana', 'bundling', 'free gift', 'other')`,
);
await queryRunner.query(
`CREATE TABLE "item_queues" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."item_queues_status_enum" NOT NULL DEFAULT 'draft', "name" character varying NOT NULL, "item_type" "public"."item_queues_item_type_enum" NOT NULL DEFAULT 'tiket masuk', CONSTRAINT "PK_e19adb0b99d995e8f10c189985f" PRIMARY KEY ("id"))`,
);
await queryRunner.query(`ALTER TABLE "items" ADD "item_queue_id" uuid`);
await queryRunner.query(
`ALTER TABLE "items" ADD CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c" FOREIGN KEY ("item_queue_id") REFERENCES "item_queues"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c"`,
);
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "item_queue_id"`);
await queryRunner.query(`DROP TABLE "item_queues"`);
await queryRunner.query(`DROP TYPE "public"."item_queues_item_type_enum"`);
await queryRunner.query(`DROP TYPE "public"."item_queues_status_enum"`);
}
}

View File

@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ItemQueueOnDelete1729582398827 implements MigrationInterface {
name = 'ItemQueueOnDelete1729582398827';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c"`,
);
await queryRunner.query(
`ALTER TABLE "items" ADD CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c" FOREIGN KEY ("item_queue_id") REFERENCES "item_queues"("id") ON DELETE SET NULL ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c"`,
);
await queryRunner.query(
`ALTER TABLE "items" ADD CONSTRAINT "FK_2cbbeb03e176addcf60d65f7c9c" FOREIGN KEY ("item_queue_id") REFERENCES "item_queues"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTransactionIdToQueueOrder1729653046392
implements MigrationInterface
{
name = 'AddTransactionIdToQueueOrder1729653046392';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queue_orders" ADD "transaction_id" character varying NOT NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queue_orders" DROP COLUMN "transaction_id"`,
);
}
}

View File

@ -0,0 +1,22 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddQueueTable1729756969674 implements MigrationInterface {
name = 'AddQueueTable1729756969674';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "queues" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "code" character varying NOT NULL, "status" character varying NOT NULL, "time" bigint NOT NULL, "call_time" bigint NOT NULL, "vip" boolean NOT NULL, "item_id" uuid NOT NULL, "qty" integer NOT NULL, CONSTRAINT "PK_d966f9eb39a9396658387071bb3" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD CONSTRAINT "FK_435954e9a0d9967f17e043d54b4" FOREIGN KEY ("item_id") REFERENCES "queue_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" DROP CONSTRAINT "FK_435954e9a0d9967f17e043d54b4"`,
);
await queryRunner.query(`DROP TABLE "queues"`);
}
}

View File

@ -0,0 +1,39 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddQueueBaseModel1729838994129 implements MigrationInterface {
name = 'AddQueueBaseModel1729838994129';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" ADD "creator_id" character varying(36)`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD "creator_name" character varying(125)`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD "editor_id" character varying(36)`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD "editor_name" character varying(125)`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD "created_at" bigint NOT NULL`,
);
await queryRunner.query(
`ALTER TABLE "queues" ADD "updated_at" bigint NOT NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" ALTER COLUMN "call_time" DROP NOT NULL`,
);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "updated_at"`);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "created_at"`);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "editor_name"`);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "editor_id"`);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "creator_name"`);
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "creator_id"`);
}
}

View File

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddQueueBucket1730859187883 implements MigrationInterface {
name = 'AddQueueBucket1730859187883';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "queue_bucket" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "queue_item_id" character varying NOT NULL, "date" bigint NOT NULL, "regular" integer NOT NULL, "vip" integer NOT NULL, CONSTRAINT "PK_cdd58b0d9e93e4be922da9d8bd6" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "queue_bucket"`);
}
}

View File

@ -0,0 +1,50 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTransactionAndItemRelation1731383726542
implements MigrationInterface
{
name = 'AddTransactionAndItemRelation1731383726542';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "item_id"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "item_id" uuid`,
);
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "customer_category_id"`,
);
await queryRunner.query(
`ALTER TABLE "transactions" ADD "customer_category_id" uuid`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD CONSTRAINT "FK_edb934ab033f847e3f7ed4fc0fc" FOREIGN KEY ("item_id") REFERENCES "items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "transactions" ADD CONSTRAINT "FK_08dc8138714894a66e94820766d" FOREIGN KEY ("customer_category_id") REFERENCES "vip_categories"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" DROP CONSTRAINT "FK_08dc8138714894a66e94820766d"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP CONSTRAINT "FK_edb934ab033f847e3f7ed4fc0fc"`,
);
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "customer_category_id"`,
);
await queryRunner.query(
`ALTER TABLE "transactions" ADD "customer_category_id" character varying`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "item_id"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "item_id" character varying`,
);
}
}

View File

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddItemQueueToQueue1731498661938 implements MigrationInterface {
name = 'AddItemQueueToQueue1731498661938';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" ADD "item_queue_id" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "queues" DROP COLUMN "item_queue_id"`);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddInformationToItemQueue1731570311609
implements MigrationInterface
{
name = 'AddInformationToItemQueue1731570311609';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "information" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "information"`,
);
}
}

View File

@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class ItemQueueAddTimeAndPeakLevel1733199330134
implements MigrationInterface
{
name = 'ItemQueueAddTimeAndPeakLevel1733199330134';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "max_peak_level" integer NOT NULL DEFAULT '100'`,
);
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "call_preparation" integer NOT NULL DEFAULT '5'`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "call_preparation"`,
);
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "max_peak_level"`,
);
}
}

View File

@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddNotificationConfigToItemQueue1734717058658
implements MigrationInterface
{
name = 'AddNotificationConfigToItemQueue1734717058658';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "use_notification" boolean NOT NULL DEFAULT true`,
);
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "requiring_notification" boolean NOT NULL DEFAULT false`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "requiring_notification"`,
);
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "use_notification"`,
);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddLastNotificationToQueue1734718462106
implements MigrationInterface
{
name = 'AddLastNotificationToQueue1734718462106';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" ADD "last_notification" bigint NULL`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "queues" DROP COLUMN "last_notification"`,
);
}
}

View File

@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class TransactionSettingModel1745991391299
implements MigrationInterface
{
name = 'TransactionSettingModel1745991391299';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "transaction_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "value" numeric NOT NULL DEFAULT '100', CONSTRAINT "PK_db7fb38a439358b499ebdee4761" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "transaction_settings"`);
}
}

View File

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class BookingAuthentication1748313715598 implements MigrationInterface {
name = 'BookingAuthentication1748313715598';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "booking_verification" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "phone_number" character varying NOT NULL, "code" character varying, "tried" integer NOT NULL DEFAULT '0', "created_at" bigint NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000, "updated_at" bigint NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000, CONSTRAINT "PK_046e9288c7dd05c7259275d9fc0" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "booking_verification"`);
}
}

View File

@ -0,0 +1,27 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class CreateTimeGroupTable1748409891706 implements MigrationInterface {
name = 'CreateTimeGroupTable1748409891706';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."time_groups_status_enum" AS ENUM('active', 'cancel', 'confirmed', 'draft', 'expired', 'inactive', 'partial refund', 'pending', 'proses refund', 'refunded', 'rejected', 'settled', 'waiting')`,
);
await queryRunner.query(
`CREATE TABLE "time_groups" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "status" "public"."time_groups_status_enum" NOT NULL DEFAULT 'draft', "name" character varying NOT NULL, "start_time" TIME NOT NULL, "end_time" TIME NOT NULL, "max_usage_time" TIME NOT NULL, CONSTRAINT "PK_083d02988db7bedfe3b7c869b50" PRIMARY KEY ("id"))`,
);
await queryRunner.query(`ALTER TABLE "items" ADD "time_group_id" uuid`);
await queryRunner.query(
`ALTER TABLE "items" ADD CONSTRAINT "FK_f44f222e1808448dca1b6cc4557" FOREIGN KEY ("time_group_id") REFERENCES "time_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP CONSTRAINT "FK_f44f222e1808448dca1b6cc4557"`,
);
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "time_group_id"`);
await queryRunner.query(`DROP TABLE "time_groups"`);
await queryRunner.query(`DROP TYPE "public"."time_groups_status_enum"`);
}
}

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddColumnOtpCode1748935417155 implements MigrationInterface {
name = 'AddColumnOtpCode1748935417155';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "vip_codes" ADD "otp_code" character varying`,
);
await queryRunner.query(
`ALTER TABLE "transactions" ADD "otp_code" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "otp_code"`,
);
await queryRunner.query(`ALTER TABLE "vip_codes" DROP COLUMN "otp_code"`);
}
}

View File

@ -0,0 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class CreateTableOtpCerifications1749028279580
implements MigrationInterface
{
name = 'CreateTableOtpCerifications1749028279580';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_action_type_enum" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION')`,
);
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_source_enum" AS ENUM('POS', 'WEB')`,
);
await queryRunner.query(
`CREATE TABLE "otp_verifications" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "otp_code" character varying NOT NULL, "action_type" "public"."otp_verifications_action_type_enum" NOT NULL, "target_id" character varying, "reference" character varying, "source" "public"."otp_verifications_source_enum" NOT NULL, "is_used" boolean NOT NULL DEFAULT false, "expired_at" bigint NOT NULL, "verified_at" bigint, CONSTRAINT "PK_91d17e75ac3182dba6701869b39" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "otp_verifications"`);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_source_enum"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_action_type_enum"`,
);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddColumnIsReplacedOtpVerification1749030419440
implements MigrationInterface
{
name = 'AddColumnIsReplacedOtpVerification1749030419440';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "otp_verifications" ADD "is_replaced" boolean NOT NULL DEFAULT false`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "otp_verifications" DROP COLUMN "is_replaced"`,
);
}
}

View File

@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddTableOtpVerifier1749043616622 implements MigrationInterface {
name = 'AddTableOtpVerifier1749043616622';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "otp_verifier" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "creator_id" character varying(36), "creator_name" character varying(125), "editor_id" character varying(36), "editor_name" character varying(125), "created_at" bigint NOT NULL, "updated_at" bigint NOT NULL, "name" character varying, "phone_number" character varying NOT NULL, CONSTRAINT "PK_884e2d0873fc589a1bdc477b2ea" PRIMARY KEY ("id"))`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "otp_verifier"`);
}
}

View File

@ -0,0 +1,37 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class UpdateEnumOtpActionType1749046285398
implements MigrationInterface
{
name = 'UpdateEnumOtpActionType1749046285398';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TYPE "public"."otp_verifications_action_type_enum" RENAME TO "otp_verifications_action_type_enum_old"`,
);
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_action_type_enum" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION', 'REJECT_RECONCILIATION')`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifications" ALTER COLUMN "action_type" TYPE "public"."otp_verifications_action_type_enum" USING "action_type"::"text"::"public"."otp_verifications_action_type_enum"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_action_type_enum_old"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_action_type_enum_old" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION')`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifications" ALTER COLUMN "action_type" TYPE "public"."otp_verifications_action_type_enum_old" USING "action_type"::"text"::"public"."otp_verifications_action_type_enum_old"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_action_type_enum"`,
);
await queryRunner.query(
`ALTER TYPE "public"."otp_verifications_action_type_enum_old" RENAME TO "otp_verifications_action_type_enum"`,
);
}
}

View File

@ -0,0 +1,28 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class RescheduleOtp1749524993295 implements MigrationInterface {
name = 'RescheduleOtp1749524993295';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "reschedule_verification" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "phone_number" character varying NOT NULL, "booking_id" character varying NOT NULL, "reschedule_date" character varying NOT NULL, "code" integer NOT NULL, "tried" integer NOT NULL DEFAULT '0', "created_at" bigint NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000, "updated_at" bigint NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000, CONSTRAINT "PK_d4df453337ca12771eb223323d8" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`ALTER TABLE "booking_verification" ALTER COLUMN "created_at" SET DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000`,
);
await queryRunner.query(
`ALTER TABLE "booking_verification" ALTER COLUMN "updated_at" SET DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "booking_verification" ALTER COLUMN "updated_at" SET DEFAULT (EXTRACT(epoch FROM now()) * (1000))`,
);
await queryRunner.query(
`ALTER TABLE "booking_verification" ALTER COLUMN "created_at" SET DEFAULT (EXTRACT(epoch FROM now()) * (1000))`,
);
await queryRunner.query(`DROP TABLE "reschedule_verification"`);
}
}

View File

@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddBookingDescriptionToItem1749537252986
implements MigrationInterface
{
name = 'AddBookingDescriptionToItem1749537252986';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" ADD "booking_description" text`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP COLUMN "booking_description"`,
);
}
}

View File

@ -0,0 +1,24 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddBookingParentToTransaction1749604239749
implements MigrationInterface
{
name = 'AddBookingParentToTransaction1749604239749';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "transactions" ADD "parent_id" uuid`);
await queryRunner.query(
`ALTER TABLE "transactions" ADD CONSTRAINT "FK_413e95171729ba18cabce1c31e3" FOREIGN KEY ("parent_id") REFERENCES "transactions"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transactions" DROP CONSTRAINT "FK_413e95171729ba18cabce1c31e3"`,
);
await queryRunner.query(
`ALTER TABLE "transactions" DROP COLUMN "parent_id"`,
);
}
}

View File

@ -0,0 +1,55 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddEnumOtpActionTypeAndUpdateColumnOtpVerifier1750045520332
implements MigrationInterface
{
name = 'AddEnumOtpActionTypeAndUpdateColumnOtpVerifier1750045520332';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "otp_verifier" ADD "is_all_action" boolean NOT NULL DEFAULT false`,
);
await queryRunner.query(
`CREATE TYPE "public"."otp_verifier_action_types_enum" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION', 'REJECT_RECONCILIATION', 'ACTIVATE_ITEM', 'ACTIVATE_USER', 'UPDATE_ITEM_PRICE', 'UPDATE_ITEM_DETAILS', 'CONFIRM_TRANSACTION')`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifier" ADD "action_types" "public"."otp_verifier_action_types_enum" array`,
);
await queryRunner.query(
`ALTER TYPE "public"."otp_verifications_action_type_enum" RENAME TO "otp_verifications_action_type_enum_old"`,
);
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_action_type_enum" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION', 'REJECT_RECONCILIATION', 'ACTIVATE_ITEM', 'ACTIVATE_USER', 'UPDATE_ITEM_PRICE', 'UPDATE_ITEM_DETAILS', 'CONFIRM_TRANSACTION')`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifications" ALTER COLUMN "action_type" TYPE "public"."otp_verifications_action_type_enum" USING "action_type"::"text"::"public"."otp_verifications_action_type_enum"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_action_type_enum_old"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."otp_verifications_action_type_enum_old" AS ENUM('CREATE_DISCOUNT', 'CANCEL_TRANSACTION', 'REJECT_RECONCILIATION')`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifications" ALTER COLUMN "action_type" TYPE "public"."otp_verifications_action_type_enum_old" USING "action_type"::"text"::"public"."otp_verifications_action_type_enum_old"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifications_action_type_enum"`,
);
await queryRunner.query(
`ALTER TYPE "public"."otp_verifications_action_type_enum_old" RENAME TO "otp_verifications_action_type_enum"`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifier" DROP COLUMN "action_types"`,
);
await queryRunner.query(
`DROP TYPE "public"."otp_verifier_action_types_enum"`,
);
await queryRunner.query(
`ALTER TABLE "otp_verifier" DROP COLUMN "is_all_action"`,
);
}
}

View File

@ -0,0 +1,29 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddUsageTypeToItem1750319148269 implements MigrationInterface {
name = 'AddUsageTypeToItem1750319148269';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."item_queues_usage_type_enum" AS ENUM('one_time', 'multiple')`,
);
await queryRunner.query(
`ALTER TABLE "item_queues" ADD "usage_type" "public"."item_queues_usage_type_enum" NOT NULL DEFAULT 'one_time'`,
);
await queryRunner.query(
`CREATE TYPE "public"."items_usage_type_enum" AS ENUM('one_time', 'multiple')`,
);
await queryRunner.query(
`ALTER TABLE "items" ADD "usage_type" "public"."items_usage_type_enum" NOT NULL DEFAULT 'one_time'`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "usage_type"`);
await queryRunner.query(`DROP TYPE "public"."items_usage_type_enum"`);
await queryRunner.query(
`ALTER TABLE "item_queues" DROP COLUMN "usage_type"`,
);
await queryRunner.query(`DROP TYPE "public"."item_queues_usage_type_enum"`);
}
}

View File

@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class RemoveItemNameUnique1750834308368 implements MigrationInterface {
name = 'RemoveItemNameUnique1750834308368';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" DROP CONSTRAINT "UQ_213736582899b3599acaade2cd1"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "items" ADD CONSTRAINT "UQ_213736582899b3599acaade2cd1" UNIQUE ("name")`,
);
}
}

View File

@ -0,0 +1,25 @@
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { ConfigModule } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { VerificationModel } from './data/models/verification.model';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BookingAuthenticationController } from './infrastructure/controllers/booking-authentication.controller';
import { VerificationService } from './data/services/verification.service';
import { JwtModule } from '@nestjs/jwt';
import { JWT_EXPIRED } from 'src/core/sessions/constants';
import { JWT_SECRET } from 'src/core/sessions/constants';
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forFeature([VerificationModel], CONNECTION_NAME.DEFAULT),
JwtModule.register({
secret: JWT_SECRET,
signOptions: { expiresIn: JWT_EXPIRED },
}),
],
controllers: [BookingAuthenticationController],
providers: [VerificationService],
})
export class BookingOnlineAuthModule {}

View File

@ -0,0 +1,29 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { BookingVerification } from '../../domain/entities/booking-verification.entity';
@Entity('booking_verification')
export class VerificationModel implements BookingVerification {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@Column()
phone_number: string;
@Column({ nullable: true })
code?: string;
@Column({ default: 0 })
tried: number;
@Column({ type: 'bigint', default: () => 'EXTRACT(EPOCH FROM NOW()) * 1000' })
created_at: number;
@Column({
type: 'bigint',
default: () => 'EXTRACT(EPOCH FROM NOW()) * 1000',
onUpdate: 'EXTRACT(EPOCH FROM NOW()) * 1000',
})
updated_at: number;
}

View File

@ -0,0 +1,110 @@
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { VerificationModel } from '../models/verification.model';
import { BookingVerification } from '../../domain/entities/booking-verification.entity';
import { UnprocessableEntityException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
export class VerificationService {
constructor(
@InjectRepository(VerificationModel)
private readonly verificationRepository: Repository<VerificationModel>,
private readonly jwtService: JwtService,
) {}
maxAttempts = 3;
expiredTime = 5 * 60 * 1000;
expiredTimeRegister = 1 * 60 * 1000;
async generateToken(payload: BookingVerification) {
return this.jwtService.sign({
phone_number: payload.phone_number,
name: payload.name,
created_at: payload.created_at,
});
}
async register(data: BookingVerification) {
const isProduction = process.env.NODE_ENV === 'true';
const currentTime = Math.floor(Date.now()); // current time in seconds
// Generate a 4 digit OTP code
const otpCode = Math.floor(1000 + Math.random() * 9000).toString();
let verification = await this.verificationRepository.findOne({
where: { phone_number: data.phone_number },
});
if (
isProduction &&
verification.updated_at &&
currentTime - verification.updated_at < this.expiredTimeRegister
) {
throw new UnprocessableEntityException('Please try again in 1 minute');
}
data.code = otpCode;
data.tried = 0;
data.updated_at = currentTime;
if (verification) {
// Update existing record
verification = this.verificationRepository.merge(verification, data);
} else {
// Create new record
verification = this.verificationRepository.create(data);
}
const payload = await this.verificationRepository.save(verification);
const notificationService = new WhatsappService();
notificationService.sendOtpNotification({
phone: data.phone_number,
code: otpCode,
});
return payload;
}
async findByPhoneNumber(phoneNumber: string) {
return this.verificationRepository.findOne({
where: { phone_number: phoneNumber },
});
}
async verify(data: BookingVerification): Promise<BookingVerification> {
const verification = await this.findByPhoneNumber(data.phone_number);
if (!verification) {
throw new UnprocessableEntityException('Phone number not found');
}
if (verification.tried >= this.maxAttempts) {
throw new UnprocessableEntityException(
'Too many attempts, please resend OTP Code',
);
}
if (verification.code != data.code) {
verification.tried++;
await this.verificationRepository.save(verification);
throw new UnprocessableEntityException('Invalid verification code');
}
const currentTime = Math.floor(Date.now());
if (
verification.updated_at &&
currentTime - verification.updated_at > this.expiredTime
) {
throw new UnprocessableEntityException('Verification code expired');
}
return verification;
}
async update(id: string, data: BookingVerification) {
return this.verificationRepository.update(id, data);
}
async delete(id: string) {
return this.verificationRepository.delete(id);
}
}

View File

@ -0,0 +1,9 @@
export interface BookingVerification {
id: string;
name: string;
phone_number: string;
code?: string;
tried?: number;
created_at?: number;
updated_at?: number;
}

View File

@ -0,0 +1,43 @@
import { Controller, Post, Body, Get, Param } from '@nestjs/common';
import {
BookingVerificationDto,
VerificationCodeDto,
} from '../dto/booking-verification.dto';
import { VerificationService } from '../../data/services/verification.service';
import { Public } from 'src/core/guards/domain/decorators/unprotected.guard';
import { ApiTags } from '@nestjs/swagger';
@ApiTags('Booking Authentication')
@Public()
@Controller('v1/booking-authentication')
export class BookingAuthenticationController {
constructor(
private readonly bookingAuthenticationService: VerificationService,
) {}
@Post('verify')
async verify(@Body() body: VerificationCodeDto) {
const verification = await this.bookingAuthenticationService.verify(body);
const token = await this.bookingAuthenticationService.generateToken(
verification,
);
return {
message: `Verification successful for ${verification.phone_number}`,
token,
};
}
@Post('register')
async register(@Body() body: BookingVerificationDto) {
const verification = await this.bookingAuthenticationService.register(body);
return {
message: `Verification code sent to ${verification.phone_number}`,
};
}
@Get('get-by-phone/:phone_number')
async getByPhoneNumber(@Param('phone_number') phone_number: string) {
return this.bookingAuthenticationService.findByPhoneNumber(phone_number);
}
}

View File

@ -0,0 +1,67 @@
import { BookingVerification } from '../../domain/entities/booking-verification.entity';
import { IsString, IsNotEmpty, Matches } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class BookingVerificationDto implements BookingVerification {
id: string;
@ApiProperty({
type: String,
required: true,
example: 'John Doe',
description: 'Name of the person booking',
})
@IsString()
@IsNotEmpty()
name: string;
@ApiProperty({
type: String,
required: true,
example: '628123456789',
description: 'Phone number containing only numeric characters',
})
@IsString()
@IsNotEmpty()
@Matches(/^\d+$/, {
message: 'phone_number must contain only numeric characters',
})
phone_number: string;
}
export class VerificationCodeDto implements BookingVerification {
id: string;
@ApiProperty({
type: String,
required: true,
example: 'John Doe',
description: 'Name of the person booking',
})
@IsString()
@IsNotEmpty()
name: string;
@ApiProperty({
type: String,
required: true,
example: '628123456789',
description: 'Phone number containing only numeric characters',
})
@IsString()
@IsNotEmpty()
@Matches(/^\d+$/, {
message: 'phone_number must contain only numeric characters',
})
phone_number: string;
@ApiProperty({
type: String,
required: true,
example: '1234',
description: 'Verification code',
})
@IsString()
@IsNotEmpty()
code?: string;
}

View File

@ -0,0 +1,9 @@
export function generateOtp(digits = 4): number {
if (digits < 1) {
throw new Error('OTP digits must be at least 1');
}
const min = Math.pow(10, digits - 1);
const max = Math.pow(10, digits) - 1;
const otp = Math.floor(Math.random() * (max - min + 1)) + min;
return otp;
}

View File

@ -0,0 +1,36 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { RescheduleVerification } from '../../domain/entities/reschedule-verification.entity';
@Entity('reschedule_verification')
export class RescheduleVerificationModel implements RescheduleVerification {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@Column()
phone_number: string;
@Column()
booking_id: string;
@Column()
reschedule_date: string;
@Column()
code: number;
@Column({ default: 0 })
tried: number;
@Column({ type: 'bigint', default: () => 'EXTRACT(EPOCH FROM NOW()) * 1000' })
created_at: number;
@Column({
type: 'bigint',
default: () => 'EXTRACT(EPOCH FROM NOW()) * 1000',
onUpdate: 'EXTRACT(EPOCH FROM NOW()) * 1000',
})
updated_at: number;
}

View File

@ -0,0 +1,16 @@
export interface RescheduleVerification {
id: string;
name: string;
phone_number: string;
booking_id: string;
reschedule_date: string;
code: number;
tried?: number;
created_at?: number;
updated_at?: number;
}
export interface RescheduleRequest {
booking_id: string;
reschedule_date: string;
}

View File

@ -0,0 +1,67 @@
import { Injectable } from '@nestjs/common';
import { RelationParam } from 'src/core/modules/domain/entities/base-filter.entity';
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity';
import { IndexItemManager } from 'src/modules/item-related/item/domain/usecases/managers/index-item.manager';
import { SelectQueryBuilder } from 'typeorm';
@Injectable()
export class BookingItemManager extends IndexItemManager {
get relations(): RelationParam {
return {
// relation only join (for query purpose)
joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan),
selectRelations: [
'item_category',
'bundling_items',
'tenant',
'time_group',
'item_rates',
],
// relation yang hanya ingin dihitung (akan return number)
countRelations: [],
};
}
get selects(): string[] {
const parent = super.selects;
return [
...parent,
`${this.tableName}.image_url`,
'item_rates.id',
'item_rates.price',
'item_rates.season_period_id',
];
}
getResult(): PaginationResponse<ItemEntity> {
const result = super.getResult();
const { data, total } = result;
const hasRates = (this.filterParam.season_period_ids?.length ?? 0) > 0;
const items = data.map((item) => {
const currentRate = item.item_rates.find((rate) =>
this.filterParam.season_period_ids?.includes(rate.season_period_id),
);
const { item_rates, ...rest } = item;
const rate = currentRate?.['price'] ?? rest.base_price;
return {
...rest,
base_price: hasRates ? rate : rest.base_price,
};
});
return { total, data: items };
}
setQueryFilter(
queryBuilder: SelectQueryBuilder<ItemEntity>,
): SelectQueryBuilder<ItemEntity> {
const query = super.setQueryFilter(queryBuilder);
query.andWhere(`${this.tableName}.status = 'active'`);
return query;
}
}

View File

@ -0,0 +1,64 @@
import { HttpStatus } from '@nestjs/common';
import { UnprocessableEntityException } from '@nestjs/common';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { TransactionType } from 'src/modules/transaction/transaction/constants';
import { CreateTransactionManager } from 'src/modules/transaction/transaction/domain/usecases/managers/create-transaction.manager';
import { generateInvoiceCodeHelper } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/generate-invoice-code.helper';
import { mappingRevertTransaction } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/mapping-transaction.helper';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
import { v4 as uuidv4 } from 'uuid';
export class CreateBookingManager extends CreateTransactionManager {
async beforeProcess(): Promise<void> {
mappingRevertTransaction(this.data, TransactionType.ONLINE);
const id = uuidv4();
const invoiceCode = await generateInvoiceCodeHelper(
this.dataService,
'BOOK',
);
try {
const { token, redirect_url } = await this.dataServiceFirstOpt.create({
...this.data,
id,
});
Object.assign(this.data, {
payment_midtrans_token: token,
payment_midtrans_url: redirect_url,
});
} catch (error) {
console.log({ error });
throw new UnprocessableEntityException({
statusCode: HttpStatus.UNPROCESSABLE_ENTITY,
message: `Gagal! transaksi telah terbuat, silahkan periksa email untuk melanjutkan pembayaran`,
error: 'Unprocessable Entity',
});
}
Object.assign(this.data, {
id,
invoice_code: invoiceCode,
status: STATUS.PENDING,
invoice_date: new Date(),
});
return;
}
async afterProcess(): Promise<void> {
const whatsapp = new WhatsappService();
console.log(`/snap/v4/redirection/${this.data.payment_midtrans_token}`);
console.log(this.data.payment_midtrans_url);
await whatsapp.bookingRegister(
{
phone: this.data.customer_phone,
code: this.data.invoice_code,
name: this.data.customer_name,
time: this.data.booking_date,
id: this.data.id,
},
this.data.payment_total,
`snap/v4/redirection/${this.data.payment_midtrans_token}`,
);
}
}

View File

@ -0,0 +1,115 @@
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RescheduleVerificationModel } from '../../../data/models/reschedule-verification.model';
import {
RescheduleRequest,
RescheduleVerification,
} from '../../entities/reschedule-verification.entity';
import { generateOtp } from 'src/modules/booking-online/helpers/generate-otp';
import { TransactionReadService } from 'src/modules/transaction/transaction/data/services/transaction-read.service';
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
@Injectable()
export class RescheduleVerificationManager {
constructor(
@InjectRepository(RescheduleVerificationModel)
private readonly rescheduleVerificationRepository: Repository<RescheduleVerificationModel>,
private readonly transactionService: TransactionReadService,
) {}
async saveVerification(
request: RescheduleRequest,
): Promise<RescheduleVerificationModel> {
try {
const otp = generateOtp();
const transaction = await this.findDetailByBookingId(request.booking_id);
if (!transaction) {
throw new Error('Transaction not found for the provided booking id');
}
const data: Partial<RescheduleVerification> = {
code: otp,
booking_id: transaction.id,
name: transaction.customer_name,
phone_number: transaction.customer_phone,
reschedule_date: request.reschedule_date,
};
const existTransaction =
await this.rescheduleVerificationRepository.findOne({
where: {
booking_id: transaction.id,
},
});
const verification =
existTransaction ?? this.rescheduleVerificationRepository.create(data);
const result = await this.rescheduleVerificationRepository.save({
...verification,
code: otp,
});
const whatsapp = new WhatsappService();
whatsapp.sendOtpNotification({
phone: transaction.customer_phone,
code: otp.toString(),
});
// whatsapp.bookingRescheduleOTP({
// phone: transaction.customer_phone,
// code: otp.toString(),
// name: transaction.customer_name,
// time: new Date(request.reschedule_date).getTime(),
// id: transaction.id,
// });
return result;
} catch (error) {
// You can customize the error handling as needed, e.g., throw HttpException for NestJS
throw new UnprocessableEntityException(
`Failed to save reschedule verification: ${error.message}`,
);
}
}
async verifyOtp(
booking_id: string,
code: number,
): Promise<RescheduleVerificationModel> {
const verification = await this.rescheduleVerificationRepository.findOne({
where: { booking_id, code },
order: { created_at: 'DESC' },
});
if (!verification) {
throw new UnprocessableEntityException({
success: false,
message: 'Verification code not match',
});
}
// Optionally, you can implement OTP expiration logic here
if (verification.code !== code) {
// Increment tried count
verification.tried = (verification.tried || 0) + 1;
await this.rescheduleVerificationRepository.save(verification);
throw new UnprocessableEntityException({
success: false,
message: 'Invalid verification code.',
});
}
// Optionally, you can mark the verification as used or verified here
return verification;
}
async findDetailByBookingId(bookingId: string): Promise<TransactionEntity> {
const transaction = await this.transactionService.getOneByOptions({
where: { id: bookingId },
});
return transaction;
}
}

View File

@ -0,0 +1,90 @@
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { v4 as uuidv4 } from 'uuid';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { generateInvoiceCodeHelper } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/generate-invoice-code.helper';
import * as moment from 'moment';
import { TransactionItemModel } from 'src/modules/transaction/transaction/data/models/transaction-item.model';
import { RescheduleVerificationModel } from '../../../data/models/reschedule-verification.model';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
@Injectable()
export class RescheduleManager {
constructor(private serviceData: TransactionDataService) {}
async reschedule(data: RescheduleVerificationModel) {
const transaction = await this.serviceData.getTransactionWithReschedule(
data.booking_id,
);
const rescheduleDate = moment(data.reschedule_date, 'DD-MM-YYYY');
const id = uuidv4();
const invoiceCode = await generateInvoiceCodeHelper(
this.serviceData,
'BOOK',
);
const items = this.makeItemZeroPrice(transaction.items);
const transactionData = this.makeTransactionZeroPrice(transaction);
Object.assign(transactionData, {
parent_id: transaction.id,
id,
invoice_code: invoiceCode,
status: STATUS.SETTLED,
invoice_date: rescheduleDate.format('YYYY-MM-DD'),
booking_date: rescheduleDate.format('YYYY-MM-DD'),
created_at: moment().unix() * 1000,
updated_at: moment().unix() * 1000,
items,
});
await this.serviceData.getRepository().save(transactionData);
const whatsapp = new WhatsappService();
whatsapp.rescheduleCreated({
id: transactionData.id,
name: transactionData.customer_name,
phone: transactionData.customer_phone,
time: moment(transactionData.invoice_date).unix() * 1000,
code: transactionData.invoice_code,
});
return transactionData;
}
private makeItemZeroPrice(items: TransactionItemModel[]) {
return items.map((item) => {
return {
...item,
id: uuidv4(),
item_price: 0,
total_price: 0,
total_hpp: 0,
total_profit: 0,
total_profit_share: 0,
payment_total_dpp: 0,
payment_total_tax: 0,
total_net_price: 0,
};
});
}
private makeTransactionZeroPrice(transaction: TransactionModel) {
return {
...transaction,
payment_sub_total: 0,
payment_discount_total: 0,
payment_total: 0,
payment_total_pay: 0,
payment_total_share: 0,
payment_total_tax: 0,
payment_total_profit: 0,
payment_total_net_profit: 0,
payment_total_dpp: 0,
discount_percentage: 0,
};
}
}

View File

@ -0,0 +1,121 @@
import { BaseStatusDto } from 'src/core/modules/infrastructure/dto/base-status.dto';
import { ApiProperty } from '@nestjs/swagger';
import {
IsArray,
IsNumber,
IsObject,
IsString,
ValidateIf,
} from 'class-validator';
import { SeasonPeriodEntity } from 'src/modules/season-related/season-period/domain/entities/season-period.entity';
import { TransactionItemEntity } from 'src/modules/transaction/transaction/domain/entities/transaction-item.entity';
import {
TransactionPaymentType,
TransactionUserType,
} from 'src/modules/transaction/transaction/constants';
export class TransactionDto extends BaseStatusDto {
@ApiProperty({
type: Object,
required: false,
example: {
id: 'uuid',
season_type: {
id: 'uuid',
name: 'high season',
},
},
})
@IsObject()
@ValidateIf((body) => body.season_period)
season_period: SeasonPeriodEntity;
@ApiProperty({
type: String,
required: true,
example: TransactionUserType.GROUP,
})
@IsString()
customer_type: TransactionUserType;
@ApiProperty({
type: String,
required: true,
example: 'Andika',
})
@IsString()
customer_name: string;
@ApiProperty({
type: String,
required: false,
example: '0823...',
})
@ValidateIf((body) => body.customer_phone)
customer_phone: string;
@ApiProperty({
type: Date,
required: true,
example: '2024-01-01',
})
booking_date: Date;
@ApiProperty({
type: String,
required: false,
example: TransactionPaymentType.MIDTRANS,
})
payment_type: TransactionPaymentType;
@ApiProperty({
type: Number,
required: true,
example: 7000000,
})
@IsNumber()
payment_sub_total: number;
@ApiProperty({
type: Number,
required: true,
example: 3500000,
})
@IsNumber()
payment_total: number;
@ApiProperty({
type: [Object],
required: true,
example: [
{
item: {
id: '68aa12f7-2cce-422b-9bae-185eb1343b94',
created_at: '1718876384378',
status: 'active',
name: 'tes',
item_type: 'bundling',
hpp: '100000',
base_price: '100000',
limit_type: 'no limit',
limit_value: 0,
item_category: {
id: 'ab15981a-a656-4efc-856c-b2abfbe30979',
name: 'Kategori Bundling 2',
},
bundling_items: [
{
id: 'bd5a7a38-df25-4203-a1cd-bf94867946b2',
name: 'Wahana 21 panjangggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg',
},
],
tenant: null,
},
qty: 40,
total_price: 4000000,
},
],
})
@IsArray()
items: TransactionItemEntity[];
}

View File

@ -0,0 +1,47 @@
import { IsString, Matches } from 'class-validator';
import { RescheduleRequest } from 'src/modules/booking-online/order/domain/entities/reschedule-verification.entity';
import { ApiProperty } from '@nestjs/swagger';
export class RescheduleRequestDTO implements RescheduleRequest {
@ApiProperty({
type: String,
required: true,
example: '123e4567-e89b-12d3-a456-426614174000',
description: 'The unique identifier of the booking',
})
@IsString()
booking_id: string;
@ApiProperty({
type: String,
required: true,
example: '25-12-2024',
description: 'The new date for rescheduling in the format DD-MM-YYYY',
})
@IsString()
@Matches(/^(0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[0-2])-\d{4}$/, {
message: 'reschedule_date must be in the format DD-MM-YYYY',
})
reschedule_date: string;
}
export class RescheduleVerificationOTP {
@ApiProperty({
type: String,
required: true,
example: '123e4567-e89b-12d3-a456-426614174000',
description: 'The unique identifier of the booking',
})
@IsString()
booking_id: string;
@ApiProperty({
type: String,
required: true,
example: '123456',
description: 'The OTP code sent for verification',
})
@IsString()
code: string;
}

View File

@ -0,0 +1,32 @@
import { Controller, Get, Query } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { Public } from 'src/core/guards';
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { ItemReadService } from 'src/modules/item-related/item/data/services/item-read.service';
import { ItemEntity } from 'src/modules/item-related/item/domain/entities/item.entity';
import { FilterItemDto } from 'src/modules/item-related/item/infrastructure/dto/filter-item.dto';
import { BookingItemManager } from '../domain/usecases/managers/booking-item.manager';
@ApiTags('Booking Item')
@Controller('v1/booking-item')
@Public(true)
export class ItemController {
constructor(
private indexManager: BookingItemManager,
private serviceData: ItemReadService,
) {}
@Get()
async index(
@Query() params: FilterItemDto,
): Promise<PaginationResponse<ItemEntity>> {
params.limit = 1000;
params.show_to_booking = true;
params.all_item = true;
this.indexManager.setFilterParam(params);
this.indexManager.setService(this.serviceData, TABLE_NAME.ITEM);
await this.indexManager.execute();
return this.indexManager.getResult();
}
}

View File

@ -0,0 +1,274 @@
import {
Body,
Controller,
Get,
Param,
Post,
Res,
UnprocessableEntityException,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { Public } from 'src/core/guards';
import { TransactionDto } from './dto/booking-order.dto';
import { TransactionEntity } from 'src/modules/transaction/transaction/domain/entities/transaction.entity';
import { TransactionDataService } from 'src/modules/transaction/transaction/data/services/transaction-data.service';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { MidtransService } from 'src/modules/configuration/midtrans/data/services/midtrans.service';
import { CreateBookingManager } from '../domain/usecases/managers/create-booking.manager';
import * as QRCode from 'qrcode';
import { Gate } from 'src/core/response/domain/decorators/pagination.response';
import { Response } from 'express';
import {
RescheduleRequestDTO,
RescheduleVerificationOTP,
} from './dto/reschedule.dto';
import { RescheduleVerificationManager } from '../domain/usecases/managers/reschedule-verification.manager';
import { RescheduleManager } from '../domain/usecases/managers/reschedule.manager';
import { STATUS } from 'src/core/strings/constants/base.constants';
import * as moment from 'moment';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
@ApiTags('Booking Order')
@Controller('v1/booking')
@Public(true)
export class BookingOrderController {
constructor(
private createBooking: CreateBookingManager,
private serviceData: TransactionDataService,
private midtransService: MidtransService,
private rescheduleVerification: RescheduleVerificationManager,
private rescheduleManager: RescheduleManager,
) {}
@Post()
async create(@Body() data: TransactionDto) {
const payload: Partial<TransactionEntity> = data;
this.createBooking.setData(payload as any);
this.createBooking.setService(
this.serviceData,
TABLE_NAME.TRANSACTION,
this.midtransService,
);
await this.createBooking.execute();
const result = await this.createBooking.getResult();
const {
invoice_code,
status,
payment_midtrans_token,
payment_midtrans_url,
id,
} = result;
return {
id,
invoice_code,
status,
payment_midtrans_token,
payment_midtrans_url,
};
}
@Post('reschedule')
async reschedule(@Body() data: RescheduleRequestDTO) {
const transaction = await this.serviceData.getTransactionWithReschedule(
data.booking_id,
);
const today = moment().startOf('day');
const rescheduleDate = moment(data.reschedule_date, 'DD-MM-YYYY');
const rescheduleDateStartOfDay = rescheduleDate.startOf('day');
//TODO: validate session period priority
if (rescheduleDateStartOfDay.isSameOrBefore(today)) {
throw new UnprocessableEntityException(
'Reschedule date must be in the future',
);
}
if (!transaction) {
throw new UnprocessableEntityException('Transaction not found');
}
if (transaction.status !== STATUS.SETTLED) {
throw new UnprocessableEntityException('Transaction is not settled');
}
if (transaction.children_transactions.length > 0) {
throw new UnprocessableEntityException('Transaction already rescheduled');
}
if (transaction.parent_id) {
throw new UnprocessableEntityException('Transaction is a reschedule');
}
const result = await this.rescheduleVerification.saveVerification(data);
const maskedPhoneNumber = result.phone_number.replace(/.(?=.{4})/g, '*');
result.phone_number = maskedPhoneNumber;
return `Verification code sent to ${maskedPhoneNumber}`;
}
@Post('reschedule/verification')
async verificationReschedule(@Body() data: RescheduleVerificationOTP) {
const result = await this.rescheduleVerification.verifyOtp(
data.booking_id,
+data.code,
);
const reschedule = await this.rescheduleManager.reschedule(result);
const transaction = await this.get(reschedule.id);
return {
id: reschedule.id,
phone_number: result.phone_number,
name: result.name,
reschedule_date: result.reschedule_date,
transaction,
};
}
@Get(':id')
async get(@Param('id') transactionId: string) {
const data = await this.serviceData.getOneByOptions({
relations: [
'items',
'parent_transaction',
'items.item',
'items.item.time_group',
],
where: { id: transactionId },
});
const {
parent_id,
customer_name,
customer_phone,
booking_date,
invoice_code,
status,
id,
items,
parent_transaction,
} = data;
let timeGroup = null;
const usageItems = items.map((item) => {
const itemData = item.item;
if (itemData.time_group) {
const timeGroupData = itemData.time_group;
const {
id: groupId,
name,
start_time,
end_time,
max_usage_time,
} = timeGroupData;
timeGroup = {
id: groupId,
name,
start_time,
end_time,
max_usage_time,
};
}
const {
id,
item_id,
item_name,
item_price,
item_category_name,
total_price,
total_net_price,
qty,
qty_remaining,
} = item;
return {
id,
item_id,
item_name,
item_price,
item_category_name,
total_price,
total_net_price,
qty,
qty_remaining,
};
});
// Mask customer_phone with * and keep last 4 numbers
let maskedCustomerPhone = customer_phone;
if (typeof customer_phone === 'string' && customer_phone.length > 4) {
const last4 = customer_phone.slice(-4);
maskedCustomerPhone = '*'.repeat(customer_phone.length - 4) + last4;
}
let parentTransaction = undefined;
if (parent_transaction) {
const {
id: parentId,
invoice_code: parentInvoiceCode,
invoice_date: parentInvoiceDate,
} = parent_transaction;
parentTransaction = {
id: parentId,
invoice_code: parentInvoiceCode,
invoice_date: parentInvoiceDate,
};
}
return {
customer_name,
customer_phone: maskedCustomerPhone,
booking_date,
invoice_code,
status,
id,
is_reschedule: !!parent_id,
items: usageItems,
time_group: timeGroup,
parent: parentTransaction,
};
}
@Gate()
@Get('qrcode/:id')
async getQRcode(@Param('id') id: string, @Res() res: Response) {
console.log(QRCode);
const qrData = id;
const data = await QRCode.toDataURL(qrData);
res.setHeader('Content-Type', 'image/png');
const base64Data = data.split(',')[1];
const buffer = Buffer.from(base64Data, 'base64');
res.send(buffer);
}
@Post('resend-notification/:id')
async resendNotification(@Param('id') id: string) {
try {
const transaction = await this.serviceData.getOneByOptions({
where: { id },
});
const whatsappService = new WhatsappService();
const formattedDate = moment(transaction.booking_date);
const payload = {
id: transaction.id,
phone: transaction.customer_phone,
code: transaction.invoice_code,
name: transaction.customer_name,
time: formattedDate.valueOf(),
};
await whatsappService.bookingCreated(payload);
return {
message: 'Notification sent successfully',
};
} catch (error) {
throw new UnprocessableEntityException({
message: 'Failed to send notification',
});
}
}
}

View File

@ -0,0 +1,38 @@
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { ConfigModule } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ItemModel } from 'src/modules/item-related/item/data/models/item.model';
import { ItemModule } from 'src/modules/item-related/item/item.module';
import { ItemController } from './infrastructure/item.controller';
import { TransactionModule } from 'src/modules/transaction/transaction/transaction.module';
import { BookingOrderController } from './infrastructure/order.controller';
import { CreateBookingManager } from './domain/usecases/managers/create-booking.manager';
import { MidtransModule } from 'src/modules/configuration/midtrans/midtrans.module';
import { CqrsModule } from '@nestjs/cqrs';
import { RescheduleVerificationModel } from './data/models/reschedule-verification.model';
import { RescheduleVerificationManager } from './domain/usecases/managers/reschedule-verification.manager';
import { RescheduleManager } from './domain/usecases/managers/reschedule.manager';
import { BookingItemManager } from './domain/usecases/managers/booking-item.manager';
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forFeature(
[ItemModel, RescheduleVerificationModel],
CONNECTION_NAME.DEFAULT,
),
ItemModule,
TransactionModule,
MidtransModule,
CqrsModule,
],
controllers: [ItemController, BookingOrderController],
providers: [
CreateBookingManager,
RescheduleVerificationManager,
RescheduleManager,
BookingItemManager,
],
})
export class BookingOrderModule {}

Some files were not shown because too many files have changed in this diff Show More