Compare commits

..

278 Commits

Author SHA1 Message Date
shancheas 064112e731 feat: add clear couch transaction API 2025-04-14 12:06:05 +07:00
shancheas d6a238a224 fix: time not null when save queue 2025-04-03 22:11:19 +07: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
shancheas 46caaba6bd fix: add error log to whatsapp service 2025-01-30 07:01:52 +07: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
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
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
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
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
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
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
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
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
shancheas 26a6af2044 fix: register queue still sen notification
continuous-integration/drone/push Build is passing Details
2024-12-22 05:42:28 +07: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
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
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
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
firmanr 7e7d40ea1a Merge pull request 'feat/superset' (#76) from feat/superset into development
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #76
2024-08-27 02:53:05 +00:00
Firman Ramdhani 8590165755 feat: setup superset BE 2024-08-27 09:50:54 +07:00
Firman Ramdhani cb9421622d feat: setup env for superset BE 2024-08-27 09:44:49 +07:00
Firman Ramdhani dc97d5e14a feat: setup superset BE 2024-08-27 09:37:38 +07:00
firmanr 79adf156db Merge pull request 'feat: setup superset BE' (#75) from feat/superset into development
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #75
2024-08-26 12:04:40 +00:00
Firman Ramdhani 9f50d56cea feat: setup superset BE 2024-08-26 19:04:06 +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
shancheas c3950c7041 fix: update demography enum 2024-08-21 20:34:07 +07:00
shancheas 464c10722c fix: update item to update item rate 2024-08-21 18:42:53 +07:00
shancheas 9815c667f0 feat: create api to bulk update privileges
continuous-integration/drone/tag Build is passing Details
2024-08-21 17:06:20 +07:00
shancheas 84b829a7fa feat: add breakdown bundling to item transaction
continuous-integration/drone/tag Build is passing Details
2024-08-21 16:46:36 +07:00
shancheas eaf0f43a24 fix: add bundling to booking couch db
continuous-integration/drone/tag Build is passing Details
2024-08-21 11:14:41 +07:00
shancheas 22b418b257 fix: update price bundling items 2024-08-21 10:56:57 +07:00
shancheas d5adc48d9b fix: breakdown item rates wrong value
continuous-integration/drone/tag Build is passing Details
2024-08-21 10:30:05 +07:00
294 changed files with 26128 additions and 521 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

7
env/env.development vendored
View File

@ -40,3 +40,10 @@ ASSETS="https://asset.sky.eigen.co.id/"
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o" GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com" GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV

7
env/env.production vendored
View File

@ -37,3 +37,10 @@ ASSETS="https://asset.sky.eigen.co.id/"
GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o" GOOGLE_CALENDAR_KEY="AIzaSyCSg4P3uC9Z7kD1P4f3rf1BbBaz4Q-M55o"
GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com" GOOGLE_CALENDAR_ID="326464ac296874c7121825f5ef2e2799baa90b51da240f0045aae22beec10bd5@group.calendar.google.com"
SUPERSET_URL=https://dashboard.weplayground.eigen.co.id
SUPERSET_ADMIN_USERNAME=admin
SUPERSET_ADMIN_PASSWORD=admin
WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID=604883366037548
WHATSAPP_BUSINESS_ACCESS_TOKEN=EAAINOvRRiEEBO9yQsYDnYtjHZB7q1nZCwbBpRcxIGMDWajKZBtmWxNRKvPYkS95KQZBsZBOvSFyjiEg5CcCZBZBtaSZApxyV8fiA3cEyVwf7iVZBQP2YCTPRQZArMFeeXbO0uq5TGygmjsIz3M4YxcUHxPzKO4pKxIyxnzcoUZCqCSo1NqQSLVf3a0JyZAwgDXGL55dV

View File

@ -28,6 +28,7 @@
}, },
"dependencies": { "dependencies": {
"@faker-js/faker": "^8.4.1", "@faker-js/faker": "^8.4.1",
"@nestjs/axios": "^3.0.3",
"@nestjs/common": "^10.0.0", "@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.2", "@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.0.0", "@nestjs/core": "^10.0.0",
@ -39,6 +40,7 @@
"@nestjs/typeorm": "^10.0.2", "@nestjs/typeorm": "^10.0.2",
"@types/multer": "^1.4.11", "@types/multer": "^1.4.11",
"algebra.js": "^0.2.6", "algebra.js": "^0.2.6",
"axios": "^1.7.5",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.1", "class-validator": "^0.14.1",
@ -47,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",

View File

@ -45,8 +45,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';
@ -75,6 +77,22 @@ import { MailModule } from './modules/configuration/mail/mail.module';
import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model'; import { PosLogModel } from './modules/configuration/log/data/models/pos-log.model';
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 { 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';
@Module({ @Module({
imports: [ imports: [
@ -99,7 +117,9 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da
ItemModel, ItemModel,
ItemCategoryModel, ItemCategoryModel,
ItemRateModel, ItemRateModel,
ItemQueueModel,
LogModel, LogModel,
LogUserLoginModel,
NewsModel, NewsModel,
PaymentMethodModel, PaymentMethodModel,
PosLogModel, PosLogModel,
@ -115,13 +135,24 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da
TransactionTaxModel, TransactionTaxModel,
TransactionDemographyModel, TransactionDemographyModel,
TransactionItemBreakdownModel, TransactionItemBreakdownModel,
TransactionItemTaxModel,
TransactionBreakdownTaxModel,
UserModel, UserModel,
UserLoginModel,
VipCategoryModel, VipCategoryModel,
VipCodeModel, VipCodeModel,
// report // report
ReportBookmarkModel, ReportBookmarkModel,
ExportReportHistoryModel, ExportReportHistoryModel,
// Queue
QueueOrderModel,
QueueTicketModel,
QueueItemModel,
QueueModel,
QueueBucketModel,
], ],
synchronize: false, synchronize: false,
}), }),
@ -147,6 +178,7 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da
ItemCategoryModule, ItemCategoryModule,
ItemModule, ItemModule,
ItemRateModule, ItemRateModule,
ItemQueueModule,
// transaction // transaction
PaymentMethodModule, PaymentMethodModule,
@ -174,9 +206,18 @@ import { TransactionDemographyModel } from './modules/transaction/transaction/da
ReportModule, ReportModule,
ReportBookmarkModule, ReportBookmarkModule,
ReportExportModule, ReportExportModule,
ReportSummaryModule,
// superset
SupersetModule,
GateScanModule,
QueueModule,
], ],
controllers: [], controllers: [],
providers: [ providers: [
AuthService,
PrivilegeService, PrivilegeService,
/** /**
* By default all request from client will protect by JWT * By default all request from client will protect by JWT

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

@ -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

@ -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

@ -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,7 @@ 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',
} }

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',
@ -22,8 +23,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 +36,10 @@ 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',
} }

View File

@ -21,9 +21,6 @@ export class FixDemographyNationality1723716561482
await queryRunner.query( await queryRunner.query(
`ALTER TABLE "transaction_demographies" DROP CONSTRAINT "FK_a2b705884bca06c148e3b35ab04"`, `ALTER TABLE "transaction_demographies" DROP CONSTRAINT "FK_a2b705884bca06c148e3b35ab04"`,
); );
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ADD CONSTRAINT "UQ_a2b705884bca06c148e3b35ab04" UNIQUE ("transaction_id")`,
);
await queryRunner.query( await queryRunner.query(
`ALTER TABLE "transaction_demographies" ADD CONSTRAINT "FK_a2b705884bca06c148e3b35ab04" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`, `ALTER TABLE "transaction_demographies" ADD CONSTRAINT "FK_a2b705884bca06c148e3b35ab04" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
); );
@ -33,9 +30,6 @@ export class FixDemographyNationality1723716561482
await queryRunner.query( await queryRunner.query(
`ALTER TABLE "transaction_demographies" DROP CONSTRAINT "FK_a2b705884bca06c148e3b35ab04"`, `ALTER TABLE "transaction_demographies" DROP CONSTRAINT "FK_a2b705884bca06c148e3b35ab04"`,
); );
await queryRunner.query(
`ALTER TABLE "transaction_demographies" DROP CONSTRAINT "UQ_a2b705884bca06c148e3b35ab04"`,
);
await queryRunner.query( await queryRunner.query(
`ALTER TABLE "transaction_demographies" ADD CONSTRAINT "FK_a2b705884bca06c148e3b35ab04" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`, `ALTER TABLE "transaction_demographies" ADD CONSTRAINT "FK_a2b705884bca06c148e3b35ab04" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
); );

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 AddBreakdownToTransactionItem1724233193743
implements MigrationInterface
{
name = 'AddBreakdownToTransactionItem1724233193743';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_items" ADD "breakdown_bundling" boolean NOT NULL DEFAULT false`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "transaction_items" DROP COLUMN "breakdown_bundling"`,
);
}
}

View File

@ -0,0 +1,47 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class AddValueToDemography1724240624025 implements MigrationInterface {
name = 'AddValueToDemography1724240624025';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TYPE "public"."transaction_demographies_nationality_enum" RENAME TO "transaction_demographies_nationality_enum_old"`,
);
await queryRunner.query(
`CREATE TYPE "public"."transaction_demographies_nationality_enum" AS ENUM('local', 'foreign', 'mix', 'foreigner')`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" DROP DEFAULT`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" TYPE "public"."transaction_demographies_nationality_enum" USING "nationality"::"text"::"public"."transaction_demographies_nationality_enum"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" SET DEFAULT 'local'`,
);
await queryRunner.query(
`DROP TYPE "public"."transaction_demographies_nationality_enum_old"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "public"."transaction_demographies_nationality_enum_old" AS ENUM('local', 'foreign', 'mix')`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" DROP DEFAULT`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" TYPE "public"."transaction_demographies_nationality_enum_old" USING "nationality"::"text"::"public"."transaction_demographies_nationality_enum_old"`,
);
await queryRunner.query(
`ALTER TABLE "transaction_demographies" ALTER COLUMN "nationality" SET DEFAULT 'local'`,
);
await queryRunner.query(
`DROP TYPE "public"."transaction_demographies_nationality_enum"`,
);
await queryRunner.query(
`ALTER TYPE "public"."transaction_demographies_nationality_enum_old" RENAME TO "transaction_demographies_nationality_enum"`,
);
}
}

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

@ -9,14 +9,32 @@ import { CqrsModule } from '@nestjs/cqrs';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model'; import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants'; import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service'; import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service';
import { AuthAdminQueueController } from './infrastructure/auth-admin-queue.controller';
import { AuthAdminQueueOrchestrator } from './domain/auth-admin-queue.orchestrator';
import { LoginAdminQueueManager } from './domain/managers/admin-queue/login-admin-queue.manager';
import { LogoutAdminQueueManager } from './domain/managers/admin-queue/logout-admin-queue.manager';
import { UserLoginModel } from 'src/modules/user-related/user/data/models/user-login.model';
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature([UserModel], CONNECTION_NAME.DEFAULT), TypeOrmModule.forFeature(
[UserModel, UserLoginModel],
CONNECTION_NAME.DEFAULT,
),
CqrsModule, CqrsModule,
], ],
controllers: [AuthController], controllers: [AuthController, AuthAdminQueueController],
providers: [LoginManager, LogoutManager, UserDataService, AuthOrchestrator], providers: [
LoginManager,
LogoutManager,
UserDataService,
AuthOrchestrator,
// ADMIN QUEUE
AuthAdminQueueOrchestrator,
LoginAdminQueueManager,
LogoutAdminQueueManager,
],
}) })
export class AuthModule {} export class AuthModule {}

View File

@ -0,0 +1,32 @@
import { Injectable } from '@nestjs/common';
import { LoginAdminQueueManager } from './managers/admin-queue/login-admin-queue.manager';
import { LogoutAdminQueueManager } from './managers/admin-queue/logout-admin-queue.manager';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { UserDataService } from 'src/modules/user-related/user/data/services/user-data.service';
@Injectable()
export class AuthAdminQueueOrchestrator {
constructor(
private loginManager: LoginAdminQueueManager,
private logoutManager: LogoutAdminQueueManager,
private serviceData: UserDataService,
) {}
async login(data): Promise<any> {
this.loginManager.setData(data);
this.loginManager.setService(this.serviceData, TABLE_NAME.USER);
await this.loginManager.execute();
return this.loginManager.getResult();
}
async logout(userId?: string): Promise<any> {
if (userId) this.logoutManager.setData({ user_id: userId });
this.logoutManager.setService(this.serviceData, TABLE_NAME.USER);
await this.logoutManager.execute();
return this.logoutManager.getResult();
}
async forceLogout(token): Promise<any> {
return this.serviceData.forceLogout(token);
}
}

View File

@ -24,4 +24,8 @@ export class AuthOrchestrator {
await this.logoutManager.execute(); await this.logoutManager.execute();
return this.logoutManager.getResult(); return this.logoutManager.getResult();
} }
async forceLogout(token): Promise<any> {
return this.serviceData.forceLogout(token);
}
} }

View File

@ -0,0 +1,168 @@
import {
HttpStatus,
Inject,
Injectable,
Logger,
UnauthorizedException,
} from '@nestjs/common';
import { validatePassword } from 'src/core/helpers/password/bcrypt.helpers';
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { SessionService } from 'src/core/sessions';
import { STATUS } from 'src/core/strings/constants/base.constants';
import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
import { In } from 'typeorm';
import { UserRole } from 'src/modules/user-related/user/constants';
import { AppSource, LogUserType } from 'src/core/helpers/constant';
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
import { UserLoginEntity } from 'src/modules/user-related/user/domain/entities/user-login.entity';
@Injectable()
export class LoginAdminQueueManager extends BaseCustomManager<UserEntity> {
@Inject()
protected session: SessionService;
protected token;
protected userLogin;
async validateProcess(): Promise<void> {
return;
}
async beforeProcess(): Promise<void> {
return;
}
async process(): Promise<void> {
const itemLogin = await this.dataService.getLoginUserByItem(
this.data.item_id,
);
// get user active by username
this.userLogin = await this.dataService.getOneByOptions({
where: {
username: this.data.username,
status: STATUS.ACTIVE,
role: In([UserRole.QUEUE_ADMIN, UserRole.SUPERADMIN]),
},
relations: ['user_login'],
});
if (!this.userLogin) this.throwError();
// validasi password
const valid = await validatePassword(
this.data.password,
this.userLogin?.password,
);
if (!valid) this.throwError();
const userLoginItem = await this.dataService.getOneByOptions({
where: {
id: itemLogin?.user_id,
},
});
const hasLoginAsQueue = this.userLogin?.user_login?.find(
(item) => item.source === AppSource.QUEUE_ADMIN,
);
if (hasLoginAsQueue && hasLoginAsQueue?.item_id !== this.data.item_id) {
throw new UnauthorizedException({
statusCode: HttpStatus.UNAUTHORIZED,
message: `Akun anda sudah login di item "${hasLoginAsQueue?.item_name}"`,
error: 'Unauthorized',
});
}
// else if (itemLogin && itemLogin.user_id !== this.userLogin.id) {
// throw new UnauthorizedException({
// statusCode: HttpStatus.UNAUTHORIZED,
// message: `"${userLoginItem.name}" masih login sebagai admin antrian `,
// error: 'Unauthorized',
// });
// }
// * Disini untuk isi token
const tokenData = {
id: this.userLogin.id,
name: this.userLogin.name,
username: this.userLogin.username,
role: this.userLogin.role,
user_privilege_id: this.userLogin.user_privilege_id,
item_id: this.data.item_id,
item_name: this.data.item_name,
source: AppSource.QUEUE_ADMIN,
};
Logger.debug('Sign Token Admin Queue', 'LoginAdminQueueManager');
this.token = this.session.createAccessToken(tokenData);
Logger.debug('Save Login Token', 'LoginManager');
const userLoginData: UserLoginEntity = {
user_id: this.userLogin.id,
login_token: this.token,
login_date: new Date().getTime(),
source: AppSource.QUEUE_ADMIN,
role: this.userLogin.role,
item_id: this.data.item_id,
item_name: this.data.item_name,
};
if (hasLoginAsQueue?.item_id === this.data.item_id) {
Object.assign(userLoginData, { id: hasLoginAsQueue.id });
}
// Update refresh token
await this.dataService.saveUserLogin(userLoginData);
await this.publishEvents();
Logger.debug('Process Login Admin Queue Done', 'LoginAdminQueueManager');
return;
}
async afterProcess(): Promise<void> {
return;
}
getResult() {
return {
id: this.userLogin.id,
name: this.userLogin.name,
username: this.userLogin.username,
role: this.userLogin.role,
token: this.token,
item_id: this.data.item_id,
item_name: this.data.item_name,
};
}
get entityTarget(): any {
return UserModel;
}
get eventTopics(): EventTopics[] {
return [
{
topic: LogUserLoginEvent,
data: {
type: LogUserType.login,
role: this.userLogin.role,
user_id: this.userLogin.id,
username: this.userLogin.username,
created_at: new Date().getTime(),
item_id: this.data.item_id,
item_name: this.data.item_name,
source: AppSource.QUEUE_ADMIN,
},
},
];
}
// !throw errornya akan sama, untuk security
throwError() {
throw new UnauthorizedException({
statusCode: HttpStatus.UNAUTHORIZED,
message: `Gagal! username atau password tidak sesuai`,
error: 'Unauthorized',
});
}
}

View File

@ -0,0 +1,62 @@
import { AppSource, LogUserType } from 'src/core/helpers/constant';
import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base-custom.manager';
import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
export class LogoutAdminQueueManager extends BaseCustomManager<UserEntity> {
protected userLogin;
async validateProcess(): Promise<void> {
return;
}
async beforeProcess(): Promise<void> {
return;
}
async process(): Promise<void> {
const id = this.data?.user_id ?? this.user.id;
this.userLogin = await this.dataService.getOneByOptions({
where: { id },
});
await this.dataService.removeUserLogin({
user_id: id,
source: AppSource.QUEUE_ADMIN,
});
await this.publishEvents();
return;
}
async afterProcess(): Promise<void> {
return;
}
getResult() {
return `Success Logout User`;
}
get entityTarget(): any {
return UserModel;
}
get eventTopics(): EventTopics[] {
return [
{
topic: LogUserLoginEvent,
data: {
type: LogUserType.logout,
role: this.userLogin.role,
user_id: this.userLogin.id,
username: this.userLogin.name,
created_at: new Date().getTime(),
source: AppSource.QUEUE_ADMIN,
},
},
];
}
}

View File

@ -12,7 +12,11 @@ import { STATUS } from 'src/core/strings/constants/base.constants';
import { EventTopics } from 'src/core/strings/constants/interface.constants'; import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model'; import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity'; import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
import { UserLoginEvent } from '../entities/login.event'; import { Not } from 'typeorm';
import { UserRole } from 'src/modules/user-related/user/constants';
import { AppSource, LogUserType } from 'src/core/helpers/constant';
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
import { UserLoginEntity } from 'src/modules/user-related/user/domain/entities/user-login.entity';
@Injectable() @Injectable()
export class LoginManager extends BaseCustomManager<UserEntity> { export class LoginManager extends BaseCustomManager<UserEntity> {
@ -36,6 +40,7 @@ export class LoginManager extends BaseCustomManager<UserEntity> {
where: { where: {
username: this.data.username, username: this.data.username,
status: STATUS.ACTIVE, status: STATUS.ACTIVE,
role: Not(UserRole.QUEUE_ADMIN),
}, },
relations: [ relations: [
'user_privilege', 'user_privilege',
@ -58,25 +63,27 @@ export class LoginManager extends BaseCustomManager<UserEntity> {
username: this.userLogin.username, username: this.userLogin.username,
role: this.userLogin.role, role: this.userLogin.role,
user_privilege_id: this.userLogin.user_privilege_id, user_privilege_id: this.userLogin.user_privilege_id,
source: AppSource.POS_ADMIN,
}; };
Logger.debug('Sign Token', 'LoginManager'); Logger.debug('Sign Token', 'LoginManager');
this.token = this.session.createAccessToken(tokenData); this.token = this.session.createAccessToken(tokenData);
Logger.debug('refreshToken', 'LoginManager'); Logger.debug('Save Login Token', 'LoginManager');
const refreshToken = this.session.createAccessToken(tokenData); const userLoginData: UserLoginEntity = {
user_id: this.userLogin.id,
login_token: this.token,
login_date: new Date().getTime(),
source: AppSource.POS_ADMIN,
role: this.userLogin.role,
item_id: null,
item_name: null,
};
Logger.debug('Update Refresh Token', 'LoginManager');
// Update refresh token // Update refresh token
await this.dataService.update( await this.dataService.saveUserLogin(userLoginData);
this.queryRunner,
this.entityTarget,
{ id: this.userLogin.id },
{
refresh_token: refreshToken,
},
);
await this.publishEvents();
Logger.debug('Process Login Done', 'LoginManager'); Logger.debug('Process Login Done', 'LoginManager');
return; return;
} }
@ -119,11 +126,14 @@ export class LoginManager extends BaseCustomManager<UserEntity> {
get eventTopics(): EventTopics[] { get eventTopics(): EventTopics[] {
return [ return [
{ {
topic: UserLoginEvent, topic: LogUserLoginEvent,
data: { data: {
id: this.userLogin.id, type: LogUserType.login,
type: 'login', role: this.userLogin.role,
timestamp: new Date().getTime(), user_id: this.userLogin.id,
username: this.userLogin.username,
created_at: new Date().getTime(),
source: AppSource.POS_ADMIN,
}, },
}, },
]; ];

View File

@ -2,7 +2,8 @@ import { BaseCustomManager } from 'src/core/modules/domain/usecase/managers/base
import { EventTopics } from 'src/core/strings/constants/interface.constants'; import { EventTopics } from 'src/core/strings/constants/interface.constants';
import { UserModel } from 'src/modules/user-related/user/data/models/user.model'; import { UserModel } from 'src/modules/user-related/user/data/models/user.model';
import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity'; import { UserEntity } from 'src/modules/user-related/user/domain/entities/user.entity';
import { UserLogoutEvent } from '../entities/logout.event'; import { AppSource, LogUserType } from 'src/core/helpers/constant';
import { LogUserLoginEvent } from 'src/modules/configuration/log/domain/entities/log-user-login.event';
export class LogoutManager extends BaseCustomManager<UserEntity> { export class LogoutManager extends BaseCustomManager<UserEntity> {
async validateProcess(): Promise<void> { async validateProcess(): Promise<void> {
@ -14,15 +15,12 @@ export class LogoutManager extends BaseCustomManager<UserEntity> {
} }
async process(): Promise<void> { async process(): Promise<void> {
await this.dataService.update( await this.dataService.removeUserLogin({
this.queryRunner, user_id: this.user.id,
this.entityTarget, login_token: this.userProvider.token,
{ id: this.user.id }, source: AppSource.POS_ADMIN,
{ });
refresh_token: null, await this.publishEvents();
},
);
return; return;
} }
@ -41,11 +39,14 @@ export class LogoutManager extends BaseCustomManager<UserEntity> {
get eventTopics(): EventTopics[] { get eventTopics(): EventTopics[] {
return [ return [
{ {
topic: UserLogoutEvent, topic: LogUserLoginEvent,
data: { data: {
id: this.user.id, type: LogUserType.logout,
type: 'logout', role: this.user.role,
timestamp: new Date().getTime(), user_id: this.user.id,
username: this.user.name,
created_at: new Date().getTime(),
source: AppSource.POS_ADMIN,
}, },
}, },
]; ];

View File

@ -0,0 +1,35 @@
import { Body, Controller, Delete, Param, Post, Put } from '@nestjs/common';
import { ExcludePrivilege, Public } from 'src/core/guards';
import { ApiBearerAuth } from '@nestjs/swagger';
import { ForceLogoutDto, LoginQueueDto } from './dto/login.dto';
import { AuthAdminQueueOrchestrator } from '../domain/auth-admin-queue.orchestrator';
@Controller('v1/auth/queue')
export class AuthAdminQueueController {
constructor(private orchestrator: AuthAdminQueueOrchestrator) {}
@Post()
@Public(true)
async login(@Body() body: LoginQueueDto) {
return await this.orchestrator.login(body);
}
@ApiBearerAuth('JWT')
@Public(false)
@ExcludePrivilege()
@Delete('logout')
async logout() {
return await this.orchestrator.logout();
}
@Put(':user_id/logout')
async logoutQueueAdmin(@Param('user_id') userId: string) {
return await this.orchestrator.logout(userId);
}
@Post('force-logout')
@Public(true)
async forceLogout(@Body() body: ForceLogoutDto) {
return await this.orchestrator.forceLogout(body.token);
}
}

View File

@ -1,8 +1,8 @@
import { Body, Controller, Delete, Post } from '@nestjs/common'; import { Body, Controller, Delete, Post } from '@nestjs/common';
import { Public } from 'src/core/guards'; import { ExcludePrivilege, Public } from 'src/core/guards';
import { AuthOrchestrator } from '../domain/auth.orchestrator'; import { AuthOrchestrator } from '../domain/auth.orchestrator';
import { ApiBearerAuth } from '@nestjs/swagger'; import { ApiBearerAuth } from '@nestjs/swagger';
import { LoginDto } from './dto/login.dto'; import { ForceLogoutDto, LoginDto } from './dto/login.dto';
@Controller('v1/auth') @Controller('v1/auth')
export class AuthController { export class AuthController {
@ -16,8 +16,15 @@ export class AuthController {
@ApiBearerAuth('JWT') @ApiBearerAuth('JWT')
@Public(false) @Public(false)
@ExcludePrivilege()
@Delete('logout') @Delete('logout')
async logoout() { async logout() {
return await this.orchestrator.logout(); return await this.orchestrator.logout();
} }
@Post('force-logout')
@Public(true)
async forceLogout(@Body() body: ForceLogoutDto) {
return await this.orchestrator.forceLogout(body.token);
}
} }

View File

@ -11,3 +11,27 @@ export class LoginDto implements LoginRequest {
@IsString() @IsString()
password: string; password: string;
} }
export class LoginQueueDto implements LoginRequest {
@ApiProperty({ name: 'username', required: true, default: 'superadmin' })
@IsString()
username: string;
@ApiProperty({ name: 'password', required: true, default: 'Eigen123!' })
@IsString()
password: string;
@ApiProperty({ name: 'item_id', required: true, default: 'string' })
@IsString()
item_id: string;
@ApiProperty({ name: 'item_name', required: true, default: 'string' })
@IsString()
item_name: string;
}
export class ForceLogoutDto {
@ApiProperty({ required: true })
@IsString()
token: string;
}

View File

@ -51,6 +51,7 @@ import {
import { SeasonPeriodDataService } from 'src/modules/season-related/season-period/data/services/season-period-data.service'; import { SeasonPeriodDataService } from 'src/modules/season-related/season-period/data/services/season-period-data.service';
import { SeasonPeriodModel } from 'src/modules/season-related/season-period/data/models/season-period.model'; import { SeasonPeriodModel } from 'src/modules/season-related/season-period/data/models/season-period.model';
import { TransactionDemographyModel } from 'src/modules/transaction/transaction/data/models/transaction-demography.model'; import { TransactionDemographyModel } from 'src/modules/transaction/transaction/data/models/transaction-demography.model';
import { UserLoginModel } from 'src/modules/user-related/user/data/models/user-login.model';
@Module({ @Module({
imports: [ imports: [
@ -61,6 +62,7 @@ import { TransactionDemographyModel } from 'src/modules/transaction/transaction/
ItemRateModel, ItemRateModel,
SeasonPeriodModel, SeasonPeriodModel,
UserModel, UserModel,
UserLoginModel,
TransactionModel, TransactionModel,
TransactionTaxModel, TransactionTaxModel,
TransactionItemModel, TransactionItemModel,
@ -100,5 +102,6 @@ import { TransactionDemographyModel } from 'src/modules/transaction/transaction/
ItemDataService, ItemDataService,
CouchService, CouchService,
], ],
exports: [CouchService],
}) })
export class CouchModule {} export class CouchModule {}

View File

@ -19,17 +19,19 @@ export class CouchService {
} }
async onModuleInit() { async onModuleInit() {
// return;
const nano = this.nanoInstance; const nano = this.nanoInstance;
for (const database of DatabaseListen) { for (const database of DatabaseListen) {
const db = nano.db.use(database); const db = nano.db.use(database);
db.changesReader.start({ includeDocs: true }).on('change', (change) => { db.changesReader.start({ includeDocs: true }).on('change', (change) => {
Logger.log( Logger.verbose(
`Receive Data from ${database}: ${change?.id}`, `Receive Data from ${database}: ${change?.id}`,
'CouchService', 'CouchService',
); );
this.changeDoc(change, database); this.changeDoc(change, database);
}); });
// transaction
Logger.log(`start listen database ${database}`, 'CouchService'); Logger.log(`start listen database ${database}`, 'CouchService');
} }
} }
@ -94,4 +96,41 @@ export class CouchService {
return null; return null;
} }
} }
getUnixTimestampLast7Days() {
const date = new Date();
date.setDate(date.getDate() - 4);
date.setHours(0, 0, 0, 0);
return date.getTime();
}
public async clearTransactions() {
const nano = this.nanoInstance;
const transaction = nano.use('transaction');
const expiredDate = this.getUnixTimestampLast7Days();
const selectorPayment = {
created_at: {
$lt: expiredDate,
},
};
const transactions = await transaction.find({
selector: selectorPayment,
fields: ['_id', '_rev'],
limit: 100000,
});
const { docs } = transactions;
console.log(docs.length);
const deletedDocs = {
docs: docs.map((doc) => ({
_id: doc._id,
_rev: doc._rev,
_deleted: true,
})),
};
await transaction.bulk(deletedDocs);
}
} }

View File

@ -95,11 +95,12 @@ export class ChangeStatusBookingHandler
where: { where: {
id: dataID, id: dataID,
}, },
relations: ['items'], relations: ['items', 'items.bundling_items'],
}); });
mappingTransaction(booking); mappingTransaction(booking);
if (!couchData) { if (!couchData) {
console.log('save data to couch');
await this.couchService.createDoc( await this.couchService.createDoc(
{ {
_id: booking.id, _id: booking.id,
@ -108,6 +109,7 @@ export class ChangeStatusBookingHandler
'booking', 'booking',
); );
} else { } else {
console.log('update data to couch');
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {
_id: booking.id, _id: booking.id,
@ -133,6 +135,7 @@ export class BookingUpdateHandler
const dataID = data?.id ?? data?.order_id; const dataID = data?.id ?? data?.order_id;
const couchData = await this.couchService.getDoc(dataID, 'booking'); const couchData = await this.couchService.getDoc(dataID, 'booking');
console.log('update', { dataID, couchData });
if (couchData) { if (couchData) {
const booking = await this.bookingService.getOneByOptions({ const booking = await this.bookingService.getOneByOptions({
where: { where: {
@ -140,6 +143,7 @@ export class BookingUpdateHandler
}, },
relations: ['items'], relations: ['items'],
}); });
console.log({ booking });
mappingTransaction(booking); mappingTransaction(booking);
await this.couchService.updateDoc( await this.couchService.updateDoc(
{ {

View File

@ -5,13 +5,17 @@ import { Public } from 'src/core/guards';
import * as Nano from 'nano'; import * as Nano from 'nano';
import { CreateUserPrivilegeDto } from 'src/modules/user-related/user-privilege/infrastructure/dto/create-user-privilege.dto'; import { CreateUserPrivilegeDto } from 'src/modules/user-related/user-privilege/infrastructure/dto/create-user-privilege.dto';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { CouchService } from '../data/services/couch.service';
@ApiTags(`couch`) @ApiTags(`couch`)
@Controller('v1/couch') @Controller('v1/couch')
@Public() @Public()
@Injectable() @Injectable()
export class CouchDataController { export class CouchDataController {
constructor(private configService: ConfigService) {} constructor(
private configService: ConfigService,
private couchService: CouchService,
) {}
get nanoInstance() { get nanoInstance() {
const couchConfiguration = this.configService.get<string>('COUCHDB_CONFIG'); const couchConfiguration = this.configService.get<string>('COUCHDB_CONFIG');
@ -64,4 +68,11 @@ export class CouchDataController {
// return people.get(); // return people.get();
} catch (error) {} } catch (error) {}
} }
@Public(true)
@Get('clear-transactions')
async clearTransactions(): Promise<string> {
await this.couchService.clearTransactions();
return 'OK';
}
} }

View File

@ -0,0 +1,37 @@
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { UserEntity } from '../../../../user-related/user/domain/entities/user.entity';
import { Column, Entity } from 'typeorm';
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
import { LogUserLoginEntity } from '../../domain/entities/log-user-login.entity';
import { UserRole } from '../../../../user-related/user/constants';
import { AppSource, LogUserType } from 'src/core/helpers/constant';
@Entity(TABLE_NAME.LOG_USER_LOGIN)
export class LogUserLoginModel
extends BaseCoreModel<UserEntity>
implements LogUserLoginEntity
{
@Column({ type: 'enum', enum: LogUserType, nullable: true })
type: LogUserType;
@Column({ type: 'enum', enum: UserRole, nullable: true })
role: UserRole;
@Column({ type: 'uuid', nullable: true })
user_id: string;
@Column({ type: 'uuid', nullable: true })
item_id: string;
@Column({ type: 'varchar', nullable: true })
item_name: string;
@Column({ type: 'varchar', nullable: true })
username: string;
@Column({ type: 'bigint', nullable: true })
created_at: number;
@Column({ type: 'enum', enum: AppSource, nullable: true })
source: AppSource;
}

View File

@ -14,6 +14,9 @@ export class PosLogModel
@Column('bigint', { name: 'pos_number', nullable: true }) @Column('bigint', { name: 'pos_number', nullable: true })
pos_number: number; pos_number: number;
@Column('varchar', { name: 'pos_name', nullable: true })
pos_name: string;
@Column('decimal', { name: 'total_balance', nullable: true }) @Column('decimal', { name: 'total_balance', nullable: true })
total_balance: number; total_balance: number;

View File

@ -0,0 +1,21 @@
import { BaseDataService } from 'src/core/modules/data/service/base-data.service';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CONNECTION_NAME } from 'src/core/strings/constants/base.constants';
import { LogUserLoginEntity } from '../../domain/entities/log-user-login.entity';
import { LogUserLoginModel } from '../models/log-user-login.model';
@Injectable()
export class LogUserLoginService extends BaseDataService<LogUserLoginEntity> {
constructor(
@InjectRepository(LogUserLoginModel, CONNECTION_NAME.DEFAULT)
private repo: Repository<LogUserLoginModel>,
) {
super(repo);
}
async saveData(data) {
this.repo.save(data);
}
}

View File

@ -0,0 +1,13 @@
import { LogUserType } from 'src/core/helpers/constant';
import { UserRole } from '../../../../user-related/user/constants';
import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entity';
export interface LogUserLoginEntity extends BaseCoreEntity {
type: LogUserType;
role: UserRole;
user_id: string;
item_id: string;
item_name: string;
username: string;
created_at: number;
}

View File

@ -0,0 +1,5 @@
import { IEvent } from 'src/core/strings/constants/interface.constants';
export class LogUserLoginEvent {
constructor(public readonly data: IEvent) {}
}

View File

@ -3,6 +3,7 @@ import { BaseCoreEntity } from 'src/core/modules/domain/entities/base-core.entit
export interface PosLogEntity extends BaseCoreEntity { export interface PosLogEntity extends BaseCoreEntity {
type: PosLogType; type: PosLogType;
pos_number: number; pos_number: number;
pos_name: string;
total_balance: number; total_balance: number;
created_at: number; created_at: number;
creator_name: string; creator_name: string;

View File

@ -0,0 +1,14 @@
import { EventsHandler, IEventHandler } from '@nestjs/cqrs';
import { LogUserLoginEvent } from '../entities/log-user-login.event';
import { LogUserLoginService } from '../../data/services/log-user-login.service';
@EventsHandler(LogUserLoginEvent)
export class LogUserLoginHandler implements IEventHandler<LogUserLoginEvent> {
constructor(private service: LogUserLoginService) {}
async handle(event: LogUserLoginEvent) {
const data = event.data.data;
await this.service.saveData(data);
}
}

View File

@ -26,6 +26,7 @@ export class RecordPosLogHandler implements IEventHandler<ChangeDocEvent> {
type: PosLogType[data.type], type: PosLogType[data.type],
total_balance: data.withdrawal_cash ?? data.opening_cash_balance, total_balance: data.withdrawal_cash ?? data.opening_cash_balance,
pos_number: data.pos_number, pos_number: data.pos_number,
pos_name: data.pos_name,
creator_id: data.pos_admin?.id, creator_id: data.pos_admin?.id,
creator_name: data.pos_admin?.name ?? data.pos_admin?.username, creator_name: data.pos_admin?.name ?? data.pos_admin?.username,
drawn_by_id: data.withdraw_user?.id, drawn_by_id: data.withdraw_user?.id,

View File

@ -12,12 +12,15 @@ import { LogService } from './data/services/log.service';
import { PosLogModel } from './data/models/pos-log.model'; import { PosLogModel } from './data/models/pos-log.model';
import { PosLogService } from './data/services/pos-log.service'; import { PosLogService } from './data/services/pos-log.service';
import { RecordPosLogHandler } from './domain/handlers/pos-log.handler'; import { RecordPosLogHandler } from './domain/handlers/pos-log.handler';
import { LogUserLoginModel } from './data/models/log-user-login.model';
import { LogUserLoginService } from './data/services/log-user-login.service';
import { LogUserLoginHandler } from './domain/handlers/log-user-login.handler';
@Module({ @Module({
imports: [ imports: [
ConfigModule.forRoot(), ConfigModule.forRoot(),
TypeOrmModule.forFeature( TypeOrmModule.forFeature(
[LogModel, ErrorLogModel, PosLogModel], [LogModel, ErrorLogModel, PosLogModel, LogUserLoginModel],
CONNECTION_NAME.DEFAULT, CONNECTION_NAME.DEFAULT,
), ),
CqrsModule, CqrsModule,
@ -27,10 +30,12 @@ import { RecordPosLogHandler } from './domain/handlers/pos-log.handler';
RecordLogHandler, RecordLogHandler,
RecordPosLogHandler, RecordPosLogHandler,
RecordErrorLogHandler, RecordErrorLogHandler,
LogUserLoginHandler,
LogService, LogService,
PosLogService, PosLogService,
ErrorLogService, ErrorLogService,
LogUserLoginService,
], ],
}) })
export class LogModule {} export class LogModule {}

View File

@ -32,7 +32,6 @@ export class PaymentTransactionHandler
const current_data = event.data.data; const current_data = event.data.data;
const data_id = current_data.transaction_id ?? event.data.id; const data_id = current_data.transaction_id ?? event.data.id;
const from_refund = event.data.module == TABLE_NAME.REFUND; const from_refund = event.data.module == TABLE_NAME.REFUND;
console.log('payment handlet', { data_id });
const payments = await this.paymentService.getManyByOptions({ const payments = await this.paymentService.getManyByOptions({
where: { where: {
@ -106,6 +105,15 @@ export class PaymentTransactionHandler
`; `;
})} })}
</ul>`, </ul>`,
refund_items_data: transaction?.['refund']?.refund_items
?.filter((item) => Number(item.qty_refund) > 0)
.map((item) => {
return {
qty_refund: item.qty_refund,
item_name: item.transaction_item.item_name,
};
}),
}); });
} }

View File

@ -17,7 +17,7 @@ export async function sendEmail(receivers, invoiceType, attachment?) {
for (const receiver of receivers) { for (const receiver of receivers) {
try { try {
const templateName = getTemplate(receiver.payment_type, invoiceType); const templateName = getTemplate(receiver.payment_type, invoiceType);
const templatePath = `./assets/email-template/${templateName}.html`; const templatePath = `./assets/email-template/redesign/${templateName}.html`;
const templateSource = fs.readFileSync(templatePath, 'utf8'); const templateSource = fs.readFileSync(templatePath, 'utf8');
const template = handlebars.compile(templateSource); const template = handlebars.compile(templateSource);

View File

@ -0,0 +1,17 @@
import { Controller, Get, Param } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { ExcludePrivilege, Public } from 'src/core/guards';
import { SupersetService } from './superset.service';
@ApiTags(`Superset`)
@Controller(`v1/superset`)
@Public(false)
@ApiBearerAuth('JWT')
export class SupersetController {
constructor(private service: SupersetService) {}
@Get('token/:id')
@ExcludePrivilege()
async getGuestToken(@Param('id') id: string) {
return this.service.getGuestToken(id);
}
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { SupersetController } from './superset.controller';
import { SupersetService } from './superset.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
controllers: [SupersetController],
providers: [SupersetService],
})
export class SupersetModule {}

View File

@ -0,0 +1,82 @@
import { HttpService } from '@nestjs/axios';
import { Injectable, Logger } from '@nestjs/common';
import { firstValueFrom } from 'rxjs';
@Injectable()
export class SupersetService {
private readonly logger = new Logger(SupersetService.name);
private supersetURL = process.env.SUPERSET_URL + '/api';
private adminUsername = process.env.SUPERSET_ADMIN_USERNAME;
private adminPassword = process.env.SUPERSET_ADMIN_PASSWORD;
constructor(private readonly httpService: HttpService) {}
async getLoginToken() {
const data = {
username: this.adminUsername,
password: this.adminPassword,
provider: 'db',
refresh: true,
};
const response = await firstValueFrom(
this.httpService.request({
method: 'POST',
url: `${this.supersetURL}/v1/security/login`,
data: data,
}),
);
return response.data.access_token;
}
async getCSRFToken() {
const loginToken = await this.getLoginToken();
const response = await firstValueFrom(
this.httpService.request({
method: 'GET',
url: `${this.supersetURL}/v1/security/csrf_token/`,
headers: { Authorization: `Bearer ${loginToken}` },
}),
);
const cookie = response.headers['set-cookie'];
return { loginToken, csrfToken: response.data.result, cookie };
}
async getGuestToken(uuid: string) {
const { loginToken, csrfToken, cookie } = await this.getCSRFToken();
const data = {
resources: [{ type: 'dashboard', id: uuid }],
rls: [],
user: { username: 'pos_embed', first_name: 'pos', last_name: 'embed' },
};
const [requestCookie] = cookie[0].split(';');
const headers = {
Authorization: `Bearer ${loginToken}`,
Cookie: requestCookie,
'Content-Type': 'application/json',
'X-CSRFToken': `${csrfToken}`,
'Access-Control-Allow-Credentials': true,
};
const response = await firstValueFrom(
this.httpService.request({
method: 'POST',
url: `${this.supersetURL}/v1/security/guest_token/`,
data: data,
headers: headers,
}),
).catch((err) => {
this.logger.verbose({ loginToken, csrfToken });
this.logger.error(err.response.data);
throw err;
});
return response.data.token;
}
}

View File

@ -0,0 +1,11 @@
export interface GateScanEntity {
gate_id: string;
type: string;
uuid: string;
}
export interface GateLogEntity {
gate_id: string;
code: string;
error: any;
}

View File

@ -0,0 +1,8 @@
export interface GateResponseEntity {
code: number;
message: string;
}
export interface GateMasterEntity {
codes: string[];
}

View File

@ -0,0 +1,17 @@
import { Global, Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GateController } from './infrastructure/gate.controller';
@Global()
@Module({
imports: [
ConfigModule.forRoot(),
// TypeOrmModule.forFeature(
// [],
// CONNECTION_NAME.DEFAULT,
// ),
],
controllers: [GateController],
providers: [],
})
export class GateScanModule {}

View File

@ -0,0 +1,26 @@
import { IsNotEmpty, IsString } from 'class-validator';
import { GateLogEntity } from '../../domain/entity/gate-request.entity';
import { ApiProperty } from '@nestjs/swagger';
export class GateLogDto implements GateLogEntity {
@ApiProperty({
type: String,
required: true,
})
@IsNotEmpty()
@IsString()
gate_id: string;
@ApiProperty({
type: String,
required: true,
})
@IsNotEmpty()
@IsString()
code: string;
@ApiProperty({
required: false,
})
error: any;
}

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