Parcourir la source

migrasi js to ts full

pearlgw il y a 1 mois
Parent
commit
4e888c3451
100 fichiers modifiés avec 4618 ajouts et 2935 suppressions
  1. 36 8
      .env.example
  2. 4 1
      entrypoint.sh
  3. 11 45
      index.ts
  4. 397 0
      package-lock.json
  5. 5 5
      package.json
  6. 2 0
      prisma/migrations/20250722014110_add_relation_user/migration.sql
  7. 8 0
      prisma/migrations/20250722023051_add_relation/migration.sql
  8. 2 0
      prisma/migrations/20250729072052_solve/migration.sql
  9. 15 7
      prisma/schema.prisma
  10. 3 3
      prisma/seeders/DatabaseSeeder.ts
  11. 3 2
      prisma/seeders/HospitalSeeder.ts
  12. 21 10
      prisma/seeders/ProvinceSeeder.ts
  13. 4 2
      prisma/seeders/UserAreaSeeder.ts
  14. 4 2
      prisma/seeders/VendorSeeder.ts
  15. 9 21
      src/controllers/admin/CityController.ts
  16. 0 58
      src/controllers/admin/ExecutivesHistoryController.js
  17. 121 0
      src/controllers/admin/ExecutivesHistoryController.ts
  18. 0 61
      src/controllers/admin/HospitalController.js
  19. 146 0
      src/controllers/admin/HospitalController.ts
  20. 10 9
      src/controllers/admin/ProvinceController.ts
  21. 0 63
      src/controllers/admin/SalesController.js
  22. 0 29
      src/controllers/admin/StatusHistoryController.js
  23. 71 0
      src/controllers/admin/StatusHistoryController.ts
  24. 0 61
      src/controllers/admin/VendorController.js
  25. 126 0
      src/controllers/admin/VendorController.ts
  26. 0 59
      src/controllers/admin/VendorExperienceController.js
  27. 122 0
      src/controllers/admin/VendorExperienceController.ts
  28. 0 33
      src/controllers/auth/AuthControllers.js
  29. 0 16
      src/controllers/sales/AreaController.js
  30. 38 0
      src/controllers/sales/AreaController.ts
  31. 0 58
      src/controllers/sales/ExecutivesHistoryController.js
  32. 120 0
      src/controllers/sales/ExecutivesHistoryController.ts
  33. 0 49
      src/controllers/sales/HospitalController.js
  34. 110 0
      src/controllers/sales/HospitalController.ts
  35. 0 29
      src/controllers/sales/StatusHistoryController.js
  36. 71 0
      src/controllers/sales/StatusHistoryController.ts
  37. 0 60
      src/controllers/sales/VendorController.js
  38. 121 0
      src/controllers/sales/VendorExperienceController.ts
  39. 0 59
      src/controllers/sales/VendorHistoryController.js
  40. 0 61
      src/controllers/superadmin/AdminController.js
  41. 0 18
      src/controllers/superadmin/LogController.js
  42. 34 17
      src/middleware/CheckRoles.ts
  43. 31 9
      src/middleware/ExtractToken.ts
  44. 15 2
      src/repository/admin/CityRepository.ts
  45. 0 114
      src/repository/admin/ExecutivesHistoryRepository.js
  46. 184 0
      src/repository/admin/ExecutivesHistoryRepository.ts
  47. 0 153
      src/repository/admin/HospitalRepository.js
  48. 300 0
      src/repository/admin/HospitalRepository.ts
  49. 12 0
      src/repository/admin/ProvinceRepository.ts
  50. 0 261
      src/repository/admin/SalesRepository.js
  51. 0 64
      src/repository/admin/StatusHistoryRepository.js
  52. 89 0
      src/repository/admin/StatusHistoryRepository.ts
  53. 0 142
      src/repository/admin/VendorExperienceRepository.js
  54. 238 0
      src/repository/admin/VendorExperienceRepository.ts
  55. 0 118
      src/repository/admin/VendorRepository.js
  56. 247 0
      src/repository/admin/VendorRepository.ts
  57. 0 28
      src/repository/sales/AreaRepository.js
  58. 66 0
      src/repository/sales/AreaRepository.ts
  59. 0 120
      src/repository/sales/ExecutivesHistoryRepository.js
  60. 189 0
      src/repository/sales/ExecutivesHistoryRepository.ts
  61. 0 152
      src/repository/sales/HospitalRepository.js
  62. 276 0
      src/repository/sales/HospitalRepository.ts
  63. 0 70
      src/repository/sales/StatusHistoryRepository.js
  64. 115 0
      src/repository/sales/StatusHistoryRepository.ts
  65. 182 0
      src/repository/sales/VendorExperienceRepository.ts
  66. 0 134
      src/repository/sales/VendorHistoryRepository.js
  67. 0 117
      src/repository/sales/VendorRepository.js
  68. 0 219
      src/repository/superadmin/AdminRepository.js
  69. 0 24
      src/repository/superadmin/LogRepository.js
  70. 3 21
      src/resources/admin/city/CityCollection.ts
  71. 3 17
      src/resources/admin/city/CityResource.ts
  72. 0 24
      src/resources/admin/executives_history/ExecutivesHistoriCollection.js
  73. 60 0
      src/resources/admin/executives_history/ExecutivesHistoriCollection.ts
  74. 0 19
      src/resources/admin/executives_history/ExecutivesHistoriResource.js
  75. 45 0
      src/resources/admin/executives_history/ExecutivesHistoriResource.ts
  76. 0 27
      src/resources/admin/hospital/HospitalCollection.js
  77. 128 0
      src/resources/admin/hospital/HospitalCollection.ts
  78. 0 17
      src/resources/admin/hospital/HospitalResource.js
  79. 65 0
      src/resources/admin/hospital/HospitalResource.ts
  80. 3 18
      src/resources/admin/province/ProvinceCollection.ts
  81. 3 14
      src/resources/admin/province/ProvinceResource.ts
  82. 0 27
      src/resources/admin/status_history/StatusHistoryCollection.js
  83. 137 0
      src/resources/admin/status_history/StatusHistoryCollection.ts
  84. 0 26
      src/resources/admin/vendor/VendorCollection.js
  85. 112 0
      src/resources/admin/vendor/VendorCollection.ts
  86. 0 25
      src/resources/admin/vendor/VendorResource.js
  87. 85 0
      src/resources/admin/vendor/VendorResource.ts
  88. 100 0
      src/resources/admin/vendor_experience/VendorExperienceCollection.ts
  89. 105 0
      src/resources/admin/vendor_experience/VendorExperienceResource.ts
  90. 0 26
      src/resources/admin/vendor_history/VendorExperienceCollection.js
  91. 0 21
      src/resources/admin/vendor_history/VendorExperienceResource.js
  92. 0 7
      src/resources/auth/LoginResource.js
  93. 0 8
      src/resources/auth/UserResource.js
  94. 0 22
      src/resources/sales/area/UserAreaCollection.js
  95. 106 0
      src/resources/sales/area/UserAreaCollection.ts
  96. 0 24
      src/resources/sales/executives_history/ExecutivesHistoriCollection.js
  97. 60 0
      src/resources/sales/executives_history/ExecutivesHistoriCollection.ts
  98. 0 19
      src/resources/sales/executives_history/ExecutivesHistoriResource.js
  99. 45 0
      src/resources/sales/executives_history/ExecutivesHistoriResource.ts
  100. 0 0
      src/resources/sales/hospital/HospitalCollection.js

+ 36 - 8
.env.example

@@ -9,14 +9,42 @@
9 9
 # one found in a remote Prisma Postgres URL, does not contain any sensitive information.
10 10
 
11 11
 # Database
12
-DATABASE_URL="postgresql://postgres:postgres@localhost:5432/<namadb>"
12
+DATABASE_URL="postgresql://postgres:postgres@localhost:<port>/<name>"
13
+# DATABASE_URL="postgresql://postgres123:postgres123@db:5432/db_radar"
14
+# DATABASE_URL=postgresql://postgres123:postgres123@db:5432/db_radar
13 15
 
14 16
 PORT=3200
15 17
 
16
-# Keycloak
17
-KEYCLOAK_TOKEN_URL=<url>/realms/<name_realm>/protocol/openid-connect/token
18
-CLIENT_ID=my-app
19
-CLIENT_SECRET=vUT3dbn2EfYslBYMm0cjvvA6D5bLT2mH
20
-JWT_SECRET=FF9q223buywGKYfLbu4ojSOYJ9s63G0iJFiCwSiVXB4FOm4WJQMoOF7DubqYT46v
21
-KEYCLOAK_ADMIN_URL=<url>
22
-KEYCLOAK_REALM=<name_realm>
18
+# Keycloak lokal
19
+KEYCLOAK_TOKEN_URL=http://localhost:8020/realms/<name_realm>/protocol/openid-connect/token
20
+CLIENT_ID=<name_client>
21
+CLIENT_SECRET=<client_secret>
22
+KEYCLOAK_ADMIN_URL=http://localhost:<port_keycloak>
23
+# KEYCLOAK_REALM=pearlgw
24
+
25
+KEYCLOAK_REALM=pearlgw
26
+KEYCLOAK_CLIENT=<name_client>
27
+KEYCLOAK_URL=http://localhost:<port_keycloak>
28
+
29
+KEYCLOAK_ADMIN_CLIENT=admin-cli
30
+KEYCLOAK_ADMIN_USERNAME=<username>
31
+KEYCLOAK_ADMIN_PASSWORD=<password>
32
+
33
+# jwt
34
+JWT_SECRET=<jwt_secret>
35
+
36
+# Keycloak production
37
+# KEYCLOAK_TOKEN_URL=https://keycloak.natagw.my.id/realms/radar/protocol/openid-connect/token
38
+# CLIENT_ID=fg-radar
39
+# CLIENT_SECRET=7kVIBw6FYdHhjLRfnruLj4l8X0qlP2Yz
40
+# KEYCLOAK_ADMIN_URL=https://keycloak.natagw.my.id
41
+# KEYCLOAK_REALM=radar
42
+
43
+# Keycloak production server fg
44
+# KEYCLOAK_TOKEN_URL=https://keycloak-radar.natagw.my.id/realms/radar/protocol/openid-connect/token
45
+# CLIENT_ID=fg-radar
46
+# CLIENT_SECRET=t6qZPIqOuukAsZWDLyi9CMHFE9mva4cs
47
+# KEYCLOAK_ADMIN_URL=https://keycloak-radar.natagw.my.id
48
+# KEYCLOAK_REALM=radar
49
+
50
+BASE_URL=http://localhost:3200

+ 4 - 1
entrypoint.sh

@@ -13,4 +13,7 @@ npx prisma migrate dev --name init
13 13
 # npx prisma db seed
14 14
 
15 15
 echo "🚀 Menjalankan aplikasi..."
16
-exec node index.js
16
+# exec node index.js
17
+exec nodemon
18
+
19
+# cara jalaninnya, kan databaseseeder dulu, setelah itu node prisma/seeders/UserAreaSeeder, HospitalSeeder, VendorSeeder

+ 11 - 45
index.ts

@@ -1,4 +1,4 @@
1
-import express, { Application } from 'express';
1
+import express, { Application, Request, Response } from 'express';
2 2
 import cors from 'cors';
3 3
 import path from 'path';
4 4
 import bodyParser from 'body-parser';
@@ -8,41 +8,13 @@ import keycloak from './src/middleware/Keycloak';
8 8
 import { config } from './config/config';
9 9
 
10 10
 import provinceRoutes from './src/routes/admin/ProvinceRoute';
11
-// import authRoutes from './src/routes/auth/AuthRoute.js';
12 11
 import cityRoutes from './src/routes/admin/CityRoute';
13
-// import salesRoutes from './src/routes/admin/SalesRoute.js';
14
-// import adminRoutes from './src/routes/superadmin/AdminRoute.js';
15
-// import hospitalRoutes from './src/routes/admin/HospitalRoute.js';
16
-// import salesHospitalRoutes from './src/routes/sales/HospitalRoute.js';
17
-// import vendorRoutes from './src/routes/admin/VendorRoute.js';
18
-// import logRoutes from './src/routes/superadmin/LogRoute.js';
19
-// import areaRoutes from './src/routes/sales/AreaRoute.js';
20
-// import vendorSalesRoutes from './src/routes/sales/VendorRoute.js';
12
+import vendorRoutes from './src/routes/admin/VendorRoute';
13
+import hospitalRoutes from './src/routes/admin/HospitalRoute';
14
+import salesHospitalRoutes from './src/routes/sales/HospitalRoute';
15
+import areaRoutes from './src/routes/sales/AreaRoute';
21 16
 
22
-import './src/utils/Scheduler'; // dijalankan di awal
23
-
24
-// const express = require('express')
25
-// const cors = require('cors')
26
-// const errorHandler = require('./src/middleware/ErrorHandler.js')
27
-// const app = express()
28
-// const path = require('path');
29
-// // const hospitalRoutes = require('./src/routes/HospitalRoute.js')
30
-// const provinceRoutes = require('./src/routes/admin/ProvinceRoute.js')
31
-// const authRoutes = require('./src/routes/auth/AuthRoute.js')
32
-// // const userRoutes = require('./src/routes/UserRoute.js')
33
-// const cityRoutes = require('./src/routes/admin/CityRoute.js')
34
-// const salesRoutes = require('./src/routes/admin/SalesRoute.js')
35
-// const adminRoutes = require('./src/routes/superadmin/AdminRoute.js')
36
-// const hospitalRoutes = require('./src/routes/admin/HospitalRoute.js')
37
-// const salesHospitalRoutes = require('./src/routes/sales/HospitalRoute.js')
38
-// const vendorRoutes = require('./src/routes/admin/VendorRoute.js')
39
-// const logRoutes = require('./src/routes/superadmin/LogRoute.js')
40
-// const areaRoutes = require('./src/routes/sales/AreaRoute.js')
41
-// const vendorSalesRoutes = require('./src/routes/sales/VendorRoute.js')
42
-// const { port } = require('./config/config.js')
43
-// const keycloak = require('./src/middleware/Keycloak.js');
44
-// import bodyParser from 'body-parser';
45
-// require("./src/utils/Scheduler.js")
17
+import './src/utils/Scheduler';
46 18
 
47 19
 const app: Application = express();
48 20
 
@@ -54,21 +26,15 @@ app.use('/storage/', express.static(path.join(__dirname, 'storage/')));
54 26
 
55 27
 const apiV1 = express.Router();
56 28
 
57
-// apiV1.use('/hospitals', hospitalRoutes);
58 29
 apiV1.use('/province', provinceRoutes);
59
-// apiV1.use('/auth', authRoutes);
60
-// apiV1.use('/user', userRoutes);
61 30
 apiV1.use('/city', cityRoutes);
62
-// apiV1.use('/sales', salesRoutes);
63
-// apiV1.use('/admin', adminRoutes);
64
-// apiV1.use('/hospital', hospitalRoutes);
65
-// apiV1.use('/hospital-area', salesHospitalRoutes);
66
-// apiV1.use('/vendor', vendorRoutes);
67
-// apiV1.use('/logs', logRoutes);
68
-// apiV1.use('/area', areaRoutes);
31
+apiV1.use('/hospital', hospitalRoutes);
32
+apiV1.use('/hospital-area', salesHospitalRoutes);
33
+apiV1.use('/vendor', vendorRoutes);
34
+apiV1.use('/area', areaRoutes);
69 35
 // apiV1.use('/vendor-sales', vendorSalesRoutes);
70 36
 
71
-app.get('/', (req, res) => {
37
+app.get('/', (req: Request, res: Response) => {
72 38
     res.send('Selamat Datang di API Radar Farmagitechs');
73 39
 });
74 40
 

+ 397 - 0
package-lock.json

@@ -22,6 +22,7 @@
22 22
         "dotenv": "^16.5.0",
23 23
         "express": "^5.1.0",
24 24
         "http-status-codes": "^2.3.0",
25
+        "joi": "^17.13.3",
25 26
         "jsonwebtoken": "^9.0.2",
26 27
         "keycloak-connect": "^26.1.1",
27 28
         "multer": "^2.0.1",
@@ -34,10 +35,12 @@
34 35
         "@types/bcrypt": "^5.0.2",
35 36
         "@types/cors": "^2.8.19",
36 37
         "@types/express": "^5.0.3",
38
+        "@types/joi": "^17.2.2",
37 39
         "@types/jsonwebtoken": "^9.0.10",
38 40
         "@types/keycloak-connect": "^4.5.4",
39 41
         "@types/multer": "^2.0.0",
40 42
         "@types/node": "^24.0.14",
43
+        "nodemon": "^3.1.10",
41 44
         "prisma": "^6.10.1",
42 45
         "ts-node": "^10.9.2",
43 46
         "typescript": "^5.8.3"
@@ -72,6 +75,21 @@
72 75
         "npm": ">=9.0.0"
73 76
       }
74 77
     },
78
+    "node_modules/@hapi/hoek": {
79
+      "version": "9.3.0",
80
+      "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
81
+      "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
82
+      "license": "BSD-3-Clause"
83
+    },
84
+    "node_modules/@hapi/topo": {
85
+      "version": "5.1.0",
86
+      "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
87
+      "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
88
+      "license": "BSD-3-Clause",
89
+      "dependencies": {
90
+        "@hapi/hoek": "^9.0.0"
91
+      }
92
+    },
75 93
     "node_modules/@jridgewell/resolve-uri": {
76 94
       "version": "3.1.2",
77 95
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@@ -182,6 +200,27 @@
182 200
         "@prisma/debug": "6.10.1"
183 201
       }
184 202
     },
203
+    "node_modules/@sideway/address": {
204
+      "version": "4.1.5",
205
+      "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
206
+      "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
207
+      "license": "BSD-3-Clause",
208
+      "dependencies": {
209
+        "@hapi/hoek": "^9.0.0"
210
+      }
211
+    },
212
+    "node_modules/@sideway/formula": {
213
+      "version": "3.0.1",
214
+      "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
215
+      "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
216
+      "license": "BSD-3-Clause"
217
+    },
218
+    "node_modules/@sideway/pinpoint": {
219
+      "version": "2.0.0",
220
+      "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
221
+      "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
222
+      "license": "BSD-3-Clause"
223
+    },
185 224
     "node_modules/@testim/chrome-version": {
186 225
       "version": "1.1.4",
187 226
       "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz",
@@ -297,6 +336,16 @@
297 336
       "dev": true,
298 337
       "license": "MIT"
299 338
     },
339
+    "node_modules/@types/joi": {
340
+      "version": "17.2.2",
341
+      "resolved": "https://registry.npmjs.org/@types/joi/-/joi-17.2.2.tgz",
342
+      "integrity": "sha512-vPvPwxn0Y4pQyqkEcMCJYxXCMYcrHqdfFX4SpF4zcqYioYexmDyxtM3OK+m/ZwGBS8/dooJ0il9qCwAdd6KFtA==",
343
+      "dev": true,
344
+      "license": "MIT",
345
+      "dependencies": {
346
+        "joi": "*"
347
+      }
348
+    },
300 349
     "node_modules/@types/jsonwebtoken": {
301 350
       "version": "9.0.10",
302 351
       "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
@@ -448,6 +497,20 @@
448 497
         "node": ">= 14"
449 498
       }
450 499
     },
500
+    "node_modules/anymatch": {
501
+      "version": "3.1.3",
502
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
503
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
504
+      "dev": true,
505
+      "license": "ISC",
506
+      "dependencies": {
507
+        "normalize-path": "^3.0.0",
508
+        "picomatch": "^2.0.4"
509
+      },
510
+      "engines": {
511
+        "node": ">= 8"
512
+      }
513
+    },
451 514
     "node_modules/append-field": {
452 515
       "version": "1.0.0",
453 516
       "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
@@ -503,6 +566,13 @@
503 566
         "proxy-from-env": "^1.1.0"
504 567
       }
505 568
     },
569
+    "node_modules/balanced-match": {
570
+      "version": "1.0.2",
571
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
572
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
573
+      "dev": true,
574
+      "license": "MIT"
575
+    },
506 576
     "node_modules/basic-ftp": {
507 577
       "version": "5.0.5",
508 578
       "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
@@ -527,6 +597,19 @@
527 597
         "node": ">= 18"
528 598
       }
529 599
     },
600
+    "node_modules/binary-extensions": {
601
+      "version": "2.3.0",
602
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
603
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
604
+      "dev": true,
605
+      "license": "MIT",
606
+      "engines": {
607
+        "node": ">=8"
608
+      },
609
+      "funding": {
610
+        "url": "https://github.com/sponsors/sindresorhus"
611
+      }
612
+    },
530 613
     "node_modules/bn.js": {
531 614
       "version": "4.12.2",
532 615
       "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
@@ -553,6 +636,30 @@
553 636
         "node": ">=18"
554 637
       }
555 638
     },
639
+    "node_modules/brace-expansion": {
640
+      "version": "1.1.12",
641
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
642
+      "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
643
+      "dev": true,
644
+      "license": "MIT",
645
+      "dependencies": {
646
+        "balanced-match": "^1.0.0",
647
+        "concat-map": "0.0.1"
648
+      }
649
+    },
650
+    "node_modules/braces": {
651
+      "version": "3.0.3",
652
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
653
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
654
+      "dev": true,
655
+      "license": "MIT",
656
+      "dependencies": {
657
+        "fill-range": "^7.1.1"
658
+      },
659
+      "engines": {
660
+        "node": ">=8"
661
+      }
662
+    },
556 663
     "node_modules/brorand": {
557 664
       "version": "1.1.0",
558 665
       "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
@@ -630,6 +737,31 @@
630 737
         "url": "https://github.com/sponsors/ljharb"
631 738
       }
632 739
     },
740
+    "node_modules/chokidar": {
741
+      "version": "3.6.0",
742
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
743
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
744
+      "dev": true,
745
+      "license": "MIT",
746
+      "dependencies": {
747
+        "anymatch": "~3.1.2",
748
+        "braces": "~3.0.2",
749
+        "glob-parent": "~5.1.2",
750
+        "is-binary-path": "~2.1.0",
751
+        "is-glob": "~4.0.1",
752
+        "normalize-path": "~3.0.0",
753
+        "readdirp": "~3.6.0"
754
+      },
755
+      "engines": {
756
+        "node": ">= 8.10.0"
757
+      },
758
+      "funding": {
759
+        "url": "https://paulmillr.com/funding/"
760
+      },
761
+      "optionalDependencies": {
762
+        "fsevents": "~2.3.2"
763
+      }
764
+    },
633 765
     "node_modules/chromedriver": {
634 766
       "version": "138.0.1",
635 767
       "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-138.0.1.tgz",
@@ -672,6 +804,13 @@
672 804
       "license": "MIT",
673 805
       "optional": true
674 806
     },
807
+    "node_modules/concat-map": {
808
+      "version": "0.0.1",
809
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
810
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
811
+      "dev": true,
812
+      "license": "MIT"
813
+    },
675 814
     "node_modules/concat-stream": {
676 815
       "version": "2.0.0",
677 816
       "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
@@ -1118,6 +1257,19 @@
1118 1257
         "pend": "~1.2.0"
1119 1258
       }
1120 1259
     },
1260
+    "node_modules/fill-range": {
1261
+      "version": "7.1.1",
1262
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
1263
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
1264
+      "dev": true,
1265
+      "license": "MIT",
1266
+      "dependencies": {
1267
+        "to-regex-range": "^5.0.1"
1268
+      },
1269
+      "engines": {
1270
+        "node": ">=8"
1271
+      }
1272
+    },
1121 1273
     "node_modules/finalhandler": {
1122 1274
       "version": "2.1.0",
1123 1275
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
@@ -1210,6 +1362,21 @@
1210 1362
         "node": ">= 0.8"
1211 1363
       }
1212 1364
     },
1365
+    "node_modules/fsevents": {
1366
+      "version": "2.3.3",
1367
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1368
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1369
+      "dev": true,
1370
+      "hasInstallScript": true,
1371
+      "license": "MIT",
1372
+      "optional": true,
1373
+      "os": [
1374
+        "darwin"
1375
+      ],
1376
+      "engines": {
1377
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1378
+      }
1379
+    },
1213 1380
     "node_modules/function-bind": {
1214 1381
       "version": "1.1.2",
1215 1382
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -1287,6 +1454,19 @@
1287 1454
         "node": ">= 14"
1288 1455
       }
1289 1456
     },
1457
+    "node_modules/glob-parent": {
1458
+      "version": "5.1.2",
1459
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1460
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1461
+      "dev": true,
1462
+      "license": "ISC",
1463
+      "dependencies": {
1464
+        "is-glob": "^4.0.1"
1465
+      },
1466
+      "engines": {
1467
+        "node": ">= 6"
1468
+      }
1469
+    },
1290 1470
     "node_modules/gopd": {
1291 1471
       "version": "1.2.0",
1292 1472
       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -1299,6 +1479,16 @@
1299 1479
         "url": "https://github.com/sponsors/ljharb"
1300 1480
       }
1301 1481
     },
1482
+    "node_modules/has-flag": {
1483
+      "version": "3.0.0",
1484
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1485
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
1486
+      "dev": true,
1487
+      "license": "MIT",
1488
+      "engines": {
1489
+        "node": ">=4"
1490
+      }
1491
+    },
1302 1492
     "node_modules/has-symbols": {
1303 1493
       "version": "1.1.0",
1304 1494
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
@@ -1430,6 +1620,13 @@
1430 1620
         "node": ">=0.10.0"
1431 1621
       }
1432 1622
     },
1623
+    "node_modules/ignore-by-default": {
1624
+      "version": "1.0.1",
1625
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
1626
+      "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
1627
+      "dev": true,
1628
+      "license": "ISC"
1629
+    },
1433 1630
     "node_modules/inherits": {
1434 1631
       "version": "2.0.4",
1435 1632
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -1469,6 +1666,52 @@
1469 1666
         "node": ">= 0.10"
1470 1667
       }
1471 1668
     },
1669
+    "node_modules/is-binary-path": {
1670
+      "version": "2.1.0",
1671
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1672
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1673
+      "dev": true,
1674
+      "license": "MIT",
1675
+      "dependencies": {
1676
+        "binary-extensions": "^2.0.0"
1677
+      },
1678
+      "engines": {
1679
+        "node": ">=8"
1680
+      }
1681
+    },
1682
+    "node_modules/is-extglob": {
1683
+      "version": "2.1.1",
1684
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1685
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1686
+      "dev": true,
1687
+      "license": "MIT",
1688
+      "engines": {
1689
+        "node": ">=0.10.0"
1690
+      }
1691
+    },
1692
+    "node_modules/is-glob": {
1693
+      "version": "4.0.3",
1694
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1695
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1696
+      "dev": true,
1697
+      "license": "MIT",
1698
+      "dependencies": {
1699
+        "is-extglob": "^2.1.1"
1700
+      },
1701
+      "engines": {
1702
+        "node": ">=0.10.0"
1703
+      }
1704
+    },
1705
+    "node_modules/is-number": {
1706
+      "version": "7.0.0",
1707
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1708
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1709
+      "dev": true,
1710
+      "license": "MIT",
1711
+      "engines": {
1712
+        "node": ">=0.12.0"
1713
+      }
1714
+    },
1472 1715
     "node_modules/is-promise": {
1473 1716
       "version": "4.0.0",
1474 1717
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
@@ -1507,6 +1750,19 @@
1507 1750
         "jiti": "lib/jiti-cli.mjs"
1508 1751
       }
1509 1752
     },
1753
+    "node_modules/joi": {
1754
+      "version": "17.13.3",
1755
+      "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
1756
+      "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
1757
+      "license": "BSD-3-Clause",
1758
+      "dependencies": {
1759
+        "@hapi/hoek": "^9.3.0",
1760
+        "@hapi/topo": "^5.1.0",
1761
+        "@sideway/address": "^4.1.5",
1762
+        "@sideway/formula": "^3.0.1",
1763
+        "@sideway/pinpoint": "^2.0.0"
1764
+      }
1765
+    },
1510 1766
     "node_modules/jsbn": {
1511 1767
       "version": "1.1.0",
1512 1768
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
@@ -1705,6 +1961,19 @@
1705 1961
       "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
1706 1962
       "license": "MIT"
1707 1963
     },
1964
+    "node_modules/minimatch": {
1965
+      "version": "3.1.2",
1966
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1967
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1968
+      "dev": true,
1969
+      "license": "ISC",
1970
+      "dependencies": {
1971
+        "brace-expansion": "^1.1.7"
1972
+      },
1973
+      "engines": {
1974
+        "node": "*"
1975
+      }
1976
+    },
1708 1977
     "node_modules/minimist": {
1709 1978
       "version": "1.2.8",
1710 1979
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
@@ -1841,6 +2110,45 @@
1841 2110
         "node-gyp-build-test": "build-test.js"
1842 2111
       }
1843 2112
     },
2113
+    "node_modules/nodemon": {
2114
+      "version": "3.1.10",
2115
+      "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz",
2116
+      "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==",
2117
+      "dev": true,
2118
+      "license": "MIT",
2119
+      "dependencies": {
2120
+        "chokidar": "^3.5.2",
2121
+        "debug": "^4",
2122
+        "ignore-by-default": "^1.0.1",
2123
+        "minimatch": "^3.1.2",
2124
+        "pstree.remy": "^1.1.8",
2125
+        "semver": "^7.5.3",
2126
+        "simple-update-notifier": "^2.0.0",
2127
+        "supports-color": "^5.5.0",
2128
+        "touch": "^3.1.0",
2129
+        "undefsafe": "^2.0.5"
2130
+      },
2131
+      "bin": {
2132
+        "nodemon": "bin/nodemon.js"
2133
+      },
2134
+      "engines": {
2135
+        "node": ">=10"
2136
+      },
2137
+      "funding": {
2138
+        "type": "opencollective",
2139
+        "url": "https://opencollective.com/nodemon"
2140
+      }
2141
+    },
2142
+    "node_modules/normalize-path": {
2143
+      "version": "3.0.0",
2144
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
2145
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
2146
+      "dev": true,
2147
+      "license": "MIT",
2148
+      "engines": {
2149
+        "node": ">=0.10.0"
2150
+      }
2151
+    },
1844 2152
     "node_modules/object-assign": {
1845 2153
       "version": "4.1.1",
1846 2154
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2031,6 +2339,19 @@
2031 2339
         "split2": "^4.1.0"
2032 2340
       }
2033 2341
     },
2342
+    "node_modules/picomatch": {
2343
+      "version": "2.3.1",
2344
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
2345
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
2346
+      "dev": true,
2347
+      "license": "MIT",
2348
+      "engines": {
2349
+        "node": ">=8.6"
2350
+      },
2351
+      "funding": {
2352
+        "url": "https://github.com/sponsors/jonschlinkert"
2353
+      }
2354
+    },
2034 2355
     "node_modules/postgres-array": {
2035 2356
       "version": "2.0.0",
2036 2357
       "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
@@ -2135,6 +2456,13 @@
2135 2456
       "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
2136 2457
       "license": "MIT"
2137 2458
     },
2459
+    "node_modules/pstree.remy": {
2460
+      "version": "1.1.8",
2461
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
2462
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
2463
+      "dev": true,
2464
+      "license": "MIT"
2465
+    },
2138 2466
     "node_modules/pump": {
2139 2467
       "version": "3.0.3",
2140 2468
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
@@ -2199,6 +2527,19 @@
2199 2527
         "node": ">= 6"
2200 2528
       }
2201 2529
     },
2530
+    "node_modules/readdirp": {
2531
+      "version": "3.6.0",
2532
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
2533
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
2534
+      "dev": true,
2535
+      "license": "MIT",
2536
+      "dependencies": {
2537
+        "picomatch": "^2.2.1"
2538
+      },
2539
+      "engines": {
2540
+        "node": ">=8.10.0"
2541
+      }
2542
+    },
2202 2543
     "node_modules/router": {
2203 2544
       "version": "2.2.0",
2204 2545
       "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
@@ -2368,6 +2709,19 @@
2368 2709
         "url": "https://github.com/sponsors/ljharb"
2369 2710
       }
2370 2711
     },
2712
+    "node_modules/simple-update-notifier": {
2713
+      "version": "2.0.0",
2714
+      "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
2715
+      "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
2716
+      "dev": true,
2717
+      "license": "MIT",
2718
+      "dependencies": {
2719
+        "semver": "^7.5.3"
2720
+      },
2721
+      "engines": {
2722
+        "node": ">=10"
2723
+      }
2724
+    },
2371 2725
     "node_modules/smart-buffer": {
2372 2726
       "version": "4.2.0",
2373 2727
       "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -2461,6 +2815,19 @@
2461 2815
         "safe-buffer": "~5.2.0"
2462 2816
       }
2463 2817
     },
2818
+    "node_modules/supports-color": {
2819
+      "version": "5.5.0",
2820
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2821
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2822
+      "dev": true,
2823
+      "license": "MIT",
2824
+      "dependencies": {
2825
+        "has-flag": "^3.0.0"
2826
+      },
2827
+      "engines": {
2828
+        "node": ">=4"
2829
+      }
2830
+    },
2464 2831
     "node_modules/tcp-port-used": {
2465 2832
       "version": "1.0.2",
2466 2833
       "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
@@ -2497,6 +2864,19 @@
2497 2864
       "license": "MIT",
2498 2865
       "optional": true
2499 2866
     },
2867
+    "node_modules/to-regex-range": {
2868
+      "version": "5.0.1",
2869
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2870
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2871
+      "dev": true,
2872
+      "license": "MIT",
2873
+      "dependencies": {
2874
+        "is-number": "^7.0.0"
2875
+      },
2876
+      "engines": {
2877
+        "node": ">=8.0"
2878
+      }
2879
+    },
2500 2880
     "node_modules/toidentifier": {
2501 2881
       "version": "1.0.1",
2502 2882
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -2506,6 +2886,16 @@
2506 2886
         "node": ">=0.6"
2507 2887
       }
2508 2888
     },
2889
+    "node_modules/touch": {
2890
+      "version": "3.1.1",
2891
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
2892
+      "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
2893
+      "dev": true,
2894
+      "license": "ISC",
2895
+      "bin": {
2896
+        "nodetouch": "bin/nodetouch.js"
2897
+      }
2898
+    },
2509 2899
     "node_modules/ts-node": {
2510 2900
       "version": "10.9.2",
2511 2901
       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
@@ -2591,6 +2981,13 @@
2591 2981
         "node": ">=14.17"
2592 2982
       }
2593 2983
     },
2984
+    "node_modules/undefsafe": {
2985
+      "version": "2.0.5",
2986
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
2987
+      "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
2988
+      "dev": true,
2989
+      "license": "MIT"
2990
+    },
2594 2991
     "node_modules/undici-types": {
2595 2992
       "version": "7.8.0",
2596 2993
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",

+ 5 - 5
package.json

@@ -1,13 +1,10 @@
1 1
 {
2 2
   "name": "proyek_radar_farmagitechs",
3 3
   "version": "1.0.0",
4
-  "main": "index.js",
4
+  "main": "index.ts",
5 5
   "type": "commonjs",
6 6
   "scripts": {
7
-    "test": "echo \"Error: no test specified\" && exit 1",
8
-    "dev": "ts-node index.ts",
9
-    "build": "tsc",
10
-    "start": "node dist/index.js"
7
+    "dev": "nodemon"
11 8
   },
12 9
   "prisma": {
13 10
     "seed": "ts-node prisma/seeders/DatabaseSeeder.ts"
@@ -30,6 +27,7 @@
30 27
     "dotenv": "^16.5.0",
31 28
     "express": "^5.1.0",
32 29
     "http-status-codes": "^2.3.0",
30
+    "joi": "^17.13.3",
33 31
     "jsonwebtoken": "^9.0.2",
34 32
     "keycloak-connect": "^26.1.1",
35 33
     "multer": "^2.0.1",
@@ -42,10 +40,12 @@
42 40
     "@types/bcrypt": "^5.0.2",
43 41
     "@types/cors": "^2.8.19",
44 42
     "@types/express": "^5.0.3",
43
+    "@types/joi": "^17.2.2",
45 44
     "@types/jsonwebtoken": "^9.0.10",
46 45
     "@types/keycloak-connect": "^4.5.4",
47 46
     "@types/multer": "^2.0.0",
48 47
     "@types/node": "^24.0.14",
48
+    "nodemon": "^3.1.10",
49 49
     "prisma": "^6.10.1",
50 50
     "ts-node": "^10.9.2",
51 51
     "typescript": "^5.8.3"

+ 2 - 0
prisma/migrations/20250722014110_add_relation_user/migration.sql

@@ -0,0 +1,2 @@
1
+-- AddForeignKey
2
+ALTER TABLE "hospitals" ADD CONSTRAINT "hospitals_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "keycloak_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

+ 8 - 0
prisma/migrations/20250722023051_add_relation/migration.sql

@@ -0,0 +1,8 @@
1
+-- AddForeignKey
2
+ALTER TABLE "vendors" ADD CONSTRAINT "vendors_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "keycloak_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
3
+
4
+-- AddForeignKey
5
+ALTER TABLE "user_areas" ADD CONSTRAINT "user_areas_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "keycloak_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
6
+
7
+-- AddForeignKey
8
+ALTER TABLE "status_histories" ADD CONSTRAINT "status_histories_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "keycloak_users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

+ 2 - 0
prisma/migrations/20250729072052_solve/migration.sql

@@ -0,0 +1,2 @@
1
+-- DropIndex
2
+DROP INDEX "provinces_name_key";

+ 15 - 7
prisma/schema.prisma

@@ -59,15 +59,19 @@ model User {
59 59
 }
60 60
 
61 61
 model UserKeycloak {
62
-  id       String @id @default(uuid())
63
-  fullname String
62
+  id            String          @id @default(uuid())
63
+  fullname      String
64
+  Hospital      Hospital[]
65
+  UserArea      UserArea[]
66
+  Vendor        Vendor[]
67
+  StatusHistory StatusHistory[]
64 68
 
65 69
   @@map("keycloak_users")
66 70
 }
67 71
 
68 72
 model Province {
69 73
   id         String     @id @default(uuid())
70
-  name       String     @unique
74
+  name       String
71 75
   cities     City[]
72 76
   hospitals  Hospital[]
73 77
   user_areas UserArea[]
@@ -115,6 +119,7 @@ model Hospital {
115 119
   deletedAt            DateTime?
116 120
   province             Province            @relation(fields: [province_id], references: [id])
117 121
   city                 City                @relation(fields: [city_id], references: [id])
122
+  user                 UserKeycloak        @relation(fields: [created_by], references: [id])
118 123
   vendor_experiences   VendorExperience[]
119 124
   executives_histories ExecutivesHistory[]
120 125
   status_histories     StatusHistory[]
@@ -133,18 +138,20 @@ model Vendor {
133 138
   createdAt          DateTime           @default(now())
134 139
   updatedAt          DateTime           @updatedAt
135 140
   deletedAt          DateTime?
141
+  user               UserKeycloak       @relation(fields: [created_by], references: [id])
136 142
   vendor_experiences VendorExperience[]
137 143
 
138 144
   @@map("vendors")
139 145
 }
140 146
 
141 147
 model UserArea {
142
-  id          String    @id @default(uuid())
148
+  id          String       @id @default(uuid())
143 149
   user_id     String
144 150
   province_id String
145
-  province    Province  @relation(fields: [province_id], references: [id])
146
-  createdAt   DateTime  @default(now())
147
-  updatedAt   DateTime  @updatedAt
151
+  province    Province     @relation(fields: [province_id], references: [id])
152
+  user        UserKeycloak @relation(fields: [user_id], references: [id])
153
+  createdAt   DateTime     @default(now())
154
+  updatedAt   DateTime     @updatedAt
148 155
   deletedAt   DateTime?
149 156
 
150 157
   @@map("user_areas")
@@ -212,6 +219,7 @@ model StatusHistory {
212 219
   new_status  ProgressStatus
213 220
   note        String?        @db.Text
214 221
   hospital    Hospital       @relation(fields: [hospital_id], references: [id])
222
+  user        UserKeycloak   @relation(fields: [user_id], references: [id])
215 223
   createdAt   DateTime       @default(now())
216 224
   updatedAt   DateTime       @updatedAt
217 225
   deletedAt   DateTime?

+ 3 - 3
prisma/seeders/DatabaseSeeder.ts

@@ -84,9 +84,9 @@ async function main(): Promise<void> {
84 84
     await seedSumateraUtaraCities();
85 85
     await seedPapuaSelatanCities();
86 86
     await seedUsers();
87
-    await seedVendors();
88
-    await seedUserAreas();
89
-    await seedHospitals();
87
+    // await seedVendors();
88
+    // await seedUserAreas();
89
+    // await seedHospitals();
90 90
 }
91 91
 
92 92
 main()

+ 3 - 2
prisma/seeders/HospitalSeeder.ts

@@ -5,8 +5,8 @@ const prisma = new PrismaClient();
5 5
 
6 6
 export async function seedHospitals(): Promise<void> {
7 7
     try {
8
-        const sales1 = await prisma.user.findFirst({ where: { username: 'sales1' } });
9
-        const sales2 = await prisma.user.findFirst({ where: { username: 'sales2' } });
8
+        const sales1 = await prisma.userKeycloak.findFirst({ where: { id: '1b50e497-159f-49c2-aa4d-466e72d796f0' } });
9
+        const sales2 = await prisma.userKeycloak.findFirst({ where: { id: '0ec065d8-547c-46e3-9980-df36b9648767' } });
10 10
 
11 11
         if (!sales1 || !sales2) {
12 12
             throw new Error('User sales1 or sales2 not found');
@@ -123,6 +123,7 @@ export async function seedHospitals(): Promise<void> {
123 123
     }
124 124
 }
125 125
 
126
+seedHospitals();
126 127
 
127 128
 // const { PrismaClient } = require('@prisma/client');
128 129
 // const prisma = new PrismaClient();

+ 21 - 10
prisma/seeders/ProvinceSeeder.ts

@@ -14,17 +14,28 @@ const provinces: string[] = [
14 14
 
15 15
 export async function seedProvinces(): Promise<void> {
16 16
     for (const name of provinces.sort()) {
17
-        await prisma.province.upsert({
18
-            where: { name }, // 'name' harus @unique di schema.prisma
19
-            create: {
20
-                name,
21
-                createdAt: now().toDate(),
22
-            },
23
-            update: {
24
-                updatedAt: now().toDate()
25
-            }
17
+        const existing = await prisma.province.findFirst({
18
+            where: { name },
26 19
         });
20
+
21
+        if (!existing || existing.deletedAt !== null) {
22
+            // Jika tidak ada atau sudah soft-deleted, buat baru
23
+            await prisma.province.create({
24
+                data: {
25
+                    name,
26
+                    createdAt: now().toDate(),
27
+                },
28
+            });
29
+        } else {
30
+            // Jika sudah ada dan aktif, update updatedAt saja (optional)
31
+            await prisma.province.update({
32
+                where: { id: existing.id },
33
+                data: {
34
+                    updatedAt: now().toDate(),
35
+                },
36
+            });
37
+        }
27 38
     }
28 39
 
29 40
     console.log('✅ Provinces seeded!');
30
-}
41
+}

+ 4 - 2
prisma/seeders/UserAreaSeeder.ts

@@ -3,8 +3,8 @@ import prisma from '../../src/prisma/PrismaClient';
3 3
 export async function seedUserAreas(): Promise<void> {
4 4
     try {
5 5
         // Ambil user dengan username 'sales1' dan 'sales2'
6
-        const sales1 = await prisma.user.findFirst({ where: { username: 'sales1' } });
7
-        const sales2 = await prisma.user.findFirst({ where: { username: 'sales2' } });
6
+        const sales1 = await prisma.userKeycloak.findFirst({ where: { id: '1b50e497-159f-49c2-aa4d-466e72d796f0' } });
7
+        const sales2 = await prisma.userKeycloak.findFirst({ where: { id: '0ec065d8-547c-46e3-9980-df36b9648767' } });
8 8
 
9 9
         if (!sales1 || !sales2) {
10 10
             throw new Error('User sales1 or sales2 not found');
@@ -38,6 +38,8 @@ export async function seedUserAreas(): Promise<void> {
38 38
     }
39 39
 }
40 40
 
41
+seedUserAreas();
42
+
41 43
 
42 44
 // const prisma = require('../../src/prisma/PrismaClient.js');
43 45
 

+ 4 - 2
prisma/seeders/VendorSeeder.ts

@@ -11,9 +11,9 @@ interface VendorInput {
11 11
 export async function seedVendors(): Promise<void> {
12 12
     try {
13 13
         // Cari user dengan username admin1
14
-        const adminUser = await prisma.user.findFirst({
14
+        const adminUser = await prisma.userKeycloak.findFirst({
15 15
             where: {
16
-                username: 'admin1',
16
+                id: 'd3dcbbbd-fc92-45cf-9520-d0a6859358f6',
17 17
             },
18 18
         });
19 19
 
@@ -62,6 +62,8 @@ export async function seedVendors(): Promise<void> {
62 62
     }
63 63
 }
64 64
 
65
+seedVendors();
66
+
65 67
 // const prisma = require('../../src/prisma/PrismaClient.js');
66 68
 
67 69
 // async function seedVendors() {

+ 9 - 21
src/controllers/admin/CityController.ts

@@ -1,28 +1,16 @@
1 1
 import { Request, Response } from 'express';
2 2
 import { CityCollection } from '../../resources/admin/city/CityCollection';
3 3
 import { CityResource } from '../../resources/admin/city/CityResource';
4
-import {
5
-    getAllCityService,
6
-    showCityService,
7
-    storeCityService,
8
-    updateCityService,
9
-    deleteCityService
10
-} from '../../services/admin/CityService';
4
+import * as CityService from '../../services/admin/CityService';
11 5
 import { PaginationParam } from '../../utils/PaginationParams';
12 6
 import { errorResponse, messageSuccessResponse } from '../../utils/Response';
13
-import {
14
-    validateStoreCityRequest,
15
-    // validateUpdateCityRequest,
16
-} from '../../validators/admin/city/CityValidators';
17
-
18
-// interface CustomRequest extends Request {
19
-//     tokenData?: any;
20
-// }
7
+import { validateStoreCityRequest, validateUpdateCityRequest, } from '../../validators/admin/city/CityValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
21 9
 
22 10
 export const getAllCity = async (req: Request, res: Response): Promise<Response> => {
23 11
     try {
24 12
         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
25
-        const { cities, total } = await getAllCityService({ page, limit, search, sortBy, orderBy });
13
+        const { cities, total } = await CityService.getAllCityService({ page, limit, search, sortBy, orderBy });
26 14
 
27 15
         return CityCollection(req, res, cities, total, page, limit, 'City data successfully retrieved');
28 16
     } catch (err) {
@@ -33,7 +21,7 @@ export const getAllCity = async (req: Request, res: Response): Promise<Response>
33 21
 export const showCity = async (req: Request, res: Response): Promise<Response> => {
34 22
     try {
35 23
         const id = req.params.id;
36
-        const data = await showCityService(id);
24
+        const data = await CityService.showCityService(id);
37 25
         return CityResource(res, data, 'Success show city');
38 26
     } catch (err) {
39 27
         return errorResponse(res, err);
@@ -43,7 +31,7 @@ export const showCity = async (req: Request, res: Response): Promise<Response> =
43 31
 export const storeCity = async (req: Request, res: Response): Promise<Response> => {
44 32
     try {
45 33
         const validatedData = validateStoreCityRequest(req.body);
46
-        await storeCityService(validatedData, req);
34
+        await CityService.storeCityService(validatedData, req as CustomRequest);
47 35
         return messageSuccessResponse(res, 'Success added city', 201);
48 36
     } catch (err) {
49 37
         return errorResponse(res, err);
@@ -53,8 +41,8 @@ export const storeCity = async (req: Request, res: Response): Promise<Response>
53 41
 export const updateCity = async (req: Request, res: Response): Promise<Response> => {
54 42
     try {
55 43
         const id = req.params.id;
56
-        // const validatedData = validateUpdateCityRequest(req.body);
57
-        // await updateCityService(validatedData, id, req);
44
+        const validatedData = validateUpdateCityRequest(req.body);
45
+        await CityService.updateCityService(validatedData, id, req as CustomRequest);
58 46
         return messageSuccessResponse(res, 'Success update city');
59 47
     } catch (err) {
60 48
         return errorResponse(res, err);
@@ -64,7 +52,7 @@ export const updateCity = async (req: Request, res: Response): Promise<Response>
64 52
 export const deleteCity = async (req: Request, res: Response): Promise<Response> => {
65 53
     try {
66 54
         const id = req.params.id;
67
-        await deleteCityService(id, req);
55
+        await CityService.deleteCityService(id, req as CustomRequest);
68 56
         return messageSuccessResponse(res, 'Success delete city');
69 57
     } catch (err) {
70 58
         return errorResponse(res, err);

+ 0 - 58
src/controllers/admin/ExecutivesHistoryController.js

@@ -1,58 +0,0 @@
1
-const { ExecutivesHistoriCollection } = require('../../resources/admin/executives_history/ExecutivesHistoriCollection.js');
2
-const { ExecutivesHistoriResource } = require('../../resources/admin/executives_history/ExecutivesHistoriResource.js');
3
-const executivesHistoryService = require('../../services/admin/ExecutivesHistoryService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest } = require('../../validators/admin/executives_history/ExecutivesHistoriValidators.js');
7
-
8
-exports.getAllExecutivesHistory = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService({
13
-            page, limit, search, sortBy, orderBy
14
-        }, req);
15
-
16
-        return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
17
-    } catch (err) {
18
-        return errorResponse(res, err);
19
-    }
20
-};
21
-
22
-exports.showExecutivesHistory = async (req, res) => {
23
-    try {
24
-        const data = await executivesHistoryService.showExecutivesHistoryService(req);
25
-        return ExecutivesHistoriResource(res, data, 'Success show executives history');
26
-    } catch (err) {
27
-        return errorResponse(res, err);
28
-    }
29
-};
30
-
31
-exports.storeExecutivesHistory = async (req, res) => {
32
-    try {
33
-        const validatedData = validateStoreExecutivesHistoryRequest(req.body);
34
-        await executivesHistoryService.storeExecutivesHistoryService(validatedData, req);
35
-        return messageSuccessResponse(res, 'Success added executives history', 201);
36
-    } catch (err) {
37
-        return errorResponse(res, err);
38
-    }
39
-}
40
-
41
-exports.updateExecutivesHistory = async (req, res) => {
42
-    try {
43
-        const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
44
-        await executivesHistoryService.updateExecutivesHistoryService(validatedData, req);
45
-        return messageSuccessResponse(res, 'Success update executives history');
46
-    } catch (err) {
47
-        return errorResponse(res, err);
48
-    }
49
-}
50
-
51
-exports.deleteExecutivesHistory = async (req, res) => {
52
-    try {
53
-        await executivesHistoryService.deleteExecutivesHistoryService(req);
54
-        return messageSuccessResponse(res, 'Success delete executives history');
55
-    } catch (err) {
56
-        return errorResponse(res, err);
57
-    }
58
-};

+ 121 - 0
src/controllers/admin/ExecutivesHistoryController.ts

@@ -0,0 +1,121 @@
1
+import { Request, Response } from 'express';
2
+import { ExecutivesHistoriCollection } from '../../resources/admin/executives_history/ExecutivesHistoriCollection';
3
+import { ExecutivesHistoriResource } from '../../resources/admin/executives_history/ExecutivesHistoriResource';
4
+import * as executivesHistoryService from '../../services/admin/ExecutivesHistoryService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest, } from '../../validators/admin/executives_history/ExecutivesHistoriValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
13
+
14
+        const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService(
15
+            { page, limit, search, sortBy, orderBy },
16
+            req
17
+        );
18
+
19
+        return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
20
+    } catch (err) {
21
+        return errorResponse(res, err);
22
+    }
23
+};
24
+
25
+export const showExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
26
+    try {
27
+        const data = await executivesHistoryService.showExecutivesHistoryService(req);
28
+        return ExecutivesHistoriResource(res, data, 'Success show executives history');
29
+    } catch (err) {
30
+        return errorResponse(res, err);
31
+    }
32
+};
33
+
34
+export const storeExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
35
+    try {
36
+        const validatedData = validateStoreExecutivesHistoryRequest(req.body);
37
+        await executivesHistoryService.storeExecutivesHistoryService(validatedData, req as CustomRequest);
38
+        return messageSuccessResponse(res, 'Success added executives history', 201);
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const updateExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
47
+        await executivesHistoryService.updateExecutivesHistoryService(validatedData, req as CustomRequest);
48
+        return messageSuccessResponse(res, 'Success update executives history');
49
+    } catch (err) {
50
+        return errorResponse(res, err);
51
+    }
52
+};
53
+
54
+export const deleteExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
55
+    try {
56
+        await executivesHistoryService.deleteExecutivesHistoryService(req as CustomRequest);
57
+        return messageSuccessResponse(res, 'Success delete executives history');
58
+    } catch (err) {
59
+        return errorResponse(res, err);
60
+    }
61
+};
62
+
63
+
64
+// const { ExecutivesHistoriCollection } = require('../../resources/admin/executives_history/ExecutivesHistoriCollection.js');
65
+// const { ExecutivesHistoriResource } = require('../../resources/admin/executives_history/ExecutivesHistoriResource.js');
66
+// const executivesHistoryService = require('../../services/admin/ExecutivesHistoryService.js');
67
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
68
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
69
+// const { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest } = require('../../validators/admin/executives_history/ExecutivesHistoriValidators.js');
70
+
71
+// exports.getAllExecutivesHistory = async (req, res) => {
72
+//     try {
73
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
74
+
75
+//         const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService({
76
+//             page, limit, search, sortBy, orderBy
77
+//         }, req);
78
+
79
+//         return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
80
+//     } catch (err) {
81
+//         return errorResponse(res, err);
82
+//     }
83
+// };
84
+
85
+// exports.showExecutivesHistory = async (req, res) => {
86
+//     try {
87
+//         const data = await executivesHistoryService.showExecutivesHistoryService(req);
88
+//         return ExecutivesHistoriResource(res, data, 'Success show executives history');
89
+//     } catch (err) {
90
+//         return errorResponse(res, err);
91
+//     }
92
+// };
93
+
94
+// exports.storeExecutivesHistory = async (req, res) => {
95
+//     try {
96
+//         const validatedData = validateStoreExecutivesHistoryRequest(req.body);
97
+//         await executivesHistoryService.storeExecutivesHistoryService(validatedData, req);
98
+//         return messageSuccessResponse(res, 'Success added executives history', 201);
99
+//     } catch (err) {
100
+//         return errorResponse(res, err);
101
+//     }
102
+// }
103
+
104
+// exports.updateExecutivesHistory = async (req, res) => {
105
+//     try {
106
+//         const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
107
+//         await executivesHistoryService.updateExecutivesHistoryService(validatedData, req);
108
+//         return messageSuccessResponse(res, 'Success update executives history');
109
+//     } catch (err) {
110
+//         return errorResponse(res, err);
111
+//     }
112
+// }
113
+
114
+// exports.deleteExecutivesHistory = async (req, res) => {
115
+//     try {
116
+//         await executivesHistoryService.deleteExecutivesHistoryService(req);
117
+//         return messageSuccessResponse(res, 'Success delete executives history');
118
+//     } catch (err) {
119
+//         return errorResponse(res, err);
120
+//     }
121
+// };

+ 0 - 61
src/controllers/admin/HospitalController.js

@@ -1,61 +0,0 @@
1
-const { HospitalCollection } = require('../../resources/admin/hospital/HospitalCollection.js');
2
-const { HospitalResource } = require('../../resources/admin/hospital/HospitalResource.js');
3
-const hospitalService = require('../../services/admin/HospitalService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreHospitalRequest, validateUpdateHospitalRequest } = require('../../validators/admin/hospital/HospitalValidators.js');
7
-
8
-exports.getAllHospital = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status } = PaginationParam(req, ['province', 'city', 'type', 'ownership', 'progress_status']);
11
-
12
-        const { hospitals, total } = await hospitalService.getAllHospitalService({
13
-            page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status
14
-        });
15
-
16
-        return HospitalCollection({ req, res, data: hospitals, total, page, limit, message: 'Hospital data successfully retrieved' });
17
-    } catch (err) {
18
-        return errorResponse(res, err);
19
-    }
20
-};
21
-
22
-exports.showHospital = async (req, res) => {
23
-    try {
24
-        const id = req.params.id;
25
-        const data = await hospitalService.showHospitalService(id);
26
-        return HospitalResource(res, data, 'Success show hospital');
27
-    } catch (err) {
28
-        return errorResponse(res, err);
29
-    }
30
-};
31
-
32
-exports.storeHospital = async (req, res) => {
33
-    try {
34
-        const validatedData = validateStoreHospitalRequest(req.body);
35
-        await hospitalService.storeHospitalService(validatedData, req);
36
-        return messageSuccessResponse(res, 'Success added hospital', 201);
37
-    } catch (err) {
38
-        return errorResponse(res, err);
39
-    }
40
-}
41
-
42
-exports.updateHospital = async (req, res) => {
43
-    try {
44
-        const id = req.params.id;
45
-        const validatedData = validateUpdateHospitalRequest(req.body);
46
-        await hospitalService.updateHospitalService(validatedData, id, req);
47
-        return messageSuccessResponse(res, 'Success update hospital');
48
-    } catch (err) {
49
-        return errorResponse(res, err);
50
-    }
51
-}
52
-
53
-exports.deleteHospital = async (req, res) => {
54
-    try {
55
-        const id = req.params.id;
56
-        await hospitalService.deleteHospitalService(id, req);
57
-        return messageSuccessResponse(res, 'Success delete hospital');
58
-    } catch (err) {
59
-        return errorResponse(res, err);
60
-    }
61
-};

+ 146 - 0
src/controllers/admin/HospitalController.ts

@@ -0,0 +1,146 @@
1
+import { Request, Response } from 'express';
2
+import { HospitalCollection } from '../../resources/admin/hospital/HospitalCollection';
3
+import { HospitalResource } from '../../resources/admin/hospital/HospitalResource';
4
+import * as HospitalService from '../../services/admin/HospitalService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreHospitalRequest, validateUpdateHospitalRequest } from '../../validators/admin/hospital/HospitalValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllHospital = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const {
13
+            page,
14
+            limit,
15
+            search,
16
+            sortBy,
17
+            orderBy,
18
+            province,
19
+            city,
20
+            type,
21
+            ownership,
22
+            progress_status
23
+        } = PaginationParam(req, ['province', 'city', 'type', 'ownership', 'progress_status']);
24
+
25
+        const { hospitals, total } = await HospitalService.getAllHospitalService({
26
+            page,
27
+            limit,
28
+            search,
29
+            sortBy,
30
+            orderBy,
31
+            province,
32
+            city,
33
+            type,
34
+            ownership,
35
+            progress_status
36
+        });
37
+
38
+        return HospitalCollection(req, res, hospitals, total, page, limit, 'Hospital data successfully retrieved');
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const showHospital = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const id = req.params.id;
47
+        const data = await HospitalService.showHospitalService(id);
48
+        return HospitalResource(res, data, 'Success show hospital');
49
+    } catch (err) {
50
+        return errorResponse(res, err);
51
+    }
52
+};
53
+
54
+export const storeHospital = async (req: Request, res: Response): Promise<Response> => {
55
+    try {
56
+        const validatedData = validateStoreHospitalRequest(req.body);
57
+        await HospitalService.storeHospitalService(validatedData, req as CustomRequest);
58
+        return messageSuccessResponse(res, 'Success added hospital', 201);
59
+    } catch (err) {
60
+        return errorResponse(res, err);
61
+    }
62
+};
63
+
64
+export const updateHospital = async (req: Request, res: Response): Promise<Response> => {
65
+    try {
66
+        const id = req.params.id;
67
+        const validatedData = validateUpdateHospitalRequest(req.body);
68
+        await HospitalService.updateHospitalService(validatedData, id, req as CustomRequest);
69
+        return messageSuccessResponse(res, 'Success update hospital');
70
+    } catch (err) {
71
+        return errorResponse(res, err);
72
+    }
73
+};
74
+
75
+export const deleteHospital = async (req: Request, res: Response): Promise<Response> => {
76
+    try {
77
+        const id = req.params.id;
78
+        await HospitalService.deleteHospitalService(id, req as CustomRequest);
79
+        return messageSuccessResponse(res, 'Success delete hospital');
80
+    } catch (err) {
81
+        return errorResponse(res, err);
82
+    }
83
+};
84
+
85
+
86
+// const { HospitalCollection } = require('../../resources/admin/hospital/HospitalCollection.js');
87
+// const { HospitalResource } = require('../../resources/admin/hospital/HospitalResource.js');
88
+// const hospitalService = require('../../services/admin/HospitalService.js');
89
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
90
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
91
+// const { validateStoreHospitalRequest, validateUpdateHospitalRequest } = require('../../validators/admin/hospital/HospitalValidators.js');
92
+
93
+// exports.getAllHospital = async (req, res) => {
94
+//     try {
95
+//         const { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status } = PaginationParam(req, ['province', 'city', 'type', 'ownership', 'progress_status']);
96
+
97
+//         const { hospitals, total } = await hospitalService.getAllHospitalService({
98
+//             page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status
99
+//         });
100
+
101
+//         return HospitalCollection({ req, res, data: hospitals, total, page, limit, message: 'Hospital data successfully retrieved' });
102
+//     } catch (err) {
103
+//         return errorResponse(res, err);
104
+//     }
105
+// };
106
+
107
+// exports.showHospital = async (req, res) => {
108
+//     try {
109
+//         const id = req.params.id;
110
+//         const data = await hospitalService.showHospitalService(id);
111
+//         return HospitalResource(res, data, 'Success show hospital');
112
+//     } catch (err) {
113
+//         return errorResponse(res, err);
114
+//     }
115
+// };
116
+
117
+// exports.storeHospital = async (req, res) => {
118
+//     try {
119
+//         const validatedData = validateStoreHospitalRequest(req.body);
120
+//         await hospitalService.storeHospitalService(validatedData, req);
121
+//         return messageSuccessResponse(res, 'Success added hospital', 201);
122
+//     } catch (err) {
123
+//         return errorResponse(res, err);
124
+//     }
125
+// }
126
+
127
+// exports.updateHospital = async (req, res) => {
128
+//     try {
129
+//         const id = req.params.id;
130
+//         const validatedData = validateUpdateHospitalRequest(req.body);
131
+//         await hospitalService.updateHospitalService(validatedData, id, req);
132
+//         return messageSuccessResponse(res, 'Success update hospital');
133
+//     } catch (err) {
134
+//         return errorResponse(res, err);
135
+//     }
136
+// }
137
+
138
+// exports.deleteHospital = async (req, res) => {
139
+//     try {
140
+//         const id = req.params.id;
141
+//         await hospitalService.deleteHospitalService(id, req);
142
+//         return messageSuccessResponse(res, 'Success delete hospital');
143
+//     } catch (err) {
144
+//         return errorResponse(res, err);
145
+//     }
146
+// };

+ 10 - 9
src/controllers/admin/ProvinceController.ts

@@ -1,16 +1,17 @@
1 1
 import { Request, Response } from 'express';
2 2
 import { ProvinceCollection } from '../../resources/admin/province/ProvinceCollection';
3 3
 import { ProvinceResource } from '../../resources/admin/province/ProvinceResource';
4
-import { getAllProvinceService, storeProvinceService, showProvinceService, updateProvinceService, deleteProvinceService } from '../../services/admin/ProvinceService';
4
+import * as ProvinceService from '../../services/admin/ProvinceService';
5 5
 import { PaginationParam } from '../../utils/PaginationParams';
6 6
 import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
-import { validateStoreProvinceRequest } from '../../validators/admin/province/ProvinceValidators';
7
+import { validateProvinceStoreRequest, validateProvinceUpdateRequest } from '../../validators/admin/province/ProvinceValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
8 9
 
9 10
 export const getAllProvince = async (req: Request, res: Response): Promise<Response> => {
10 11
     try {
11 12
         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
12 13
 
13
-        const { provinces, total } = await getAllProvinceService({
14
+        const { provinces, total } = await ProvinceService.getAllProvinceService({
14 15
             page, limit, search, sortBy, orderBy
15 16
         });
16 17
 
@@ -23,7 +24,7 @@ export const getAllProvince = async (req: Request, res: Response): Promise<Respo
23 24
 export const showProvince = async (req: Request, res: Response): Promise<Response> => {
24 25
     try {
25 26
         const id = req.params.id;
26
-        const data = await showProvinceService(id);
27
+        const data = await ProvinceService.showProvinceService(id);
27 28
         return ProvinceResource(res, data, 'Success show province');
28 29
     } catch (err) {
29 30
         return errorResponse(res, err);
@@ -32,8 +33,8 @@ export const showProvince = async (req: Request, res: Response): Promise<Respons
32 33
 
33 34
 export const storeProvince = async (req: Request, res: Response): Promise<Response> => {
34 35
     try {
35
-        const validatedData = validateStoreProvinceRequest(req.body);
36
-        await storeProvinceService(validatedData, req);
36
+        const validatedData = validateProvinceStoreRequest(req.body);
37
+        await ProvinceService.storeProvinceService(validatedData, req as CustomRequest);
37 38
         return messageSuccessResponse(res, 'Success added province', 201);
38 39
     } catch (err) {
39 40
         return errorResponse(res, err);
@@ -43,8 +44,8 @@ export const storeProvince = async (req: Request, res: Response): Promise<Respon
43 44
 export const updateProvince = async (req: Request, res: Response): Promise<Response> => {
44 45
     try {
45 46
         const id = req.params.id;
46
-        const validatedData = validateStoreProvinceRequest(req.body);
47
-        await updateProvinceService(validatedData, id, req);
47
+        const validatedData = validateProvinceUpdateRequest(req.body);
48
+        await ProvinceService.updateProvinceService(validatedData, id, req as CustomRequest);
48 49
         return messageSuccessResponse(res, 'Success update province');
49 50
     } catch (err) {
50 51
         return errorResponse(res, err);
@@ -54,7 +55,7 @@ export const updateProvince = async (req: Request, res: Response): Promise<Respo
54 55
 export const deleteProvince = async (req: Request, res: Response): Promise<Response> => {
55 56
     try {
56 57
         const id = req.params.id;
57
-        await deleteProvinceService(id, req);
58
+        await ProvinceService.deleteProvinceService(id, req as CustomRequest);
58 59
         return messageSuccessResponse(res, 'Success delete province');
59 60
     } catch (err) {
60 61
         return errorResponse(res, err);

+ 0 - 63
src/controllers/admin/SalesController.js

@@ -1,63 +0,0 @@
1
-const { SalesCollection } = require('../../resources/admin/sales/SalesCollection.js');
2
-const { SalesResource } = require('../../resources/admin/sales/SalesResource.js');
3
-const salesService = require('../../services/admin/SalesService.js');
4
-const { ListResponse } = require('../../utils/ListResponse.js');
5
-const { PaginationParam } = require('../../utils/PaginationParams.js');
6
-const { errorResponse, successResponse, messageSuccessResponse } = require('../../utils/Response.js');
7
-const { validateCreateSalesRequest, validateUpdateSalesRequest } = require('../../validators/admin/sales/SalesValidators.js');
8
-
9
-exports.getAllSales = async (req, res) => {
10
-    try {
11
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
12
-
13
-        const { sales, total } = await salesService.getAllSalesService({
14
-            page, limit, search, sortBy, orderBy
15
-        });
16
-
17
-        return SalesCollection(req, res, sales, total, page, limit, 'Sales data successfully retrieved');
18
-
19
-    } catch (err) {
20
-        return errorResponse(res, err);
21
-    }
22
-};
23
-
24
-exports.showSales = async (req, res) => {
25
-    try {
26
-        const id = req.params.id;
27
-        const data = await salesService.showSalesService(id);
28
-        return SalesResource(res, data, 'Success show sales');
29
-    } catch (err) {
30
-        return errorResponse(res, err);
31
-    }
32
-};
33
-
34
-exports.storeSales = async (req, res) => {
35
-    try {
36
-        const validated = validateCreateSalesRequest(req.body);
37
-        await salesService.storeSalesService(validated, req);
38
-        return messageSuccessResponse(res, 'Sales user created successfully', 201);
39
-    } catch (err) {
40
-        return errorResponse(res, err);
41
-    }
42
-}
43
-
44
-exports.updateSales = async (req, res) => {
45
-    try {
46
-        const id = req.params.id;
47
-        const validatedData = validateUpdateSalesRequest(req.body);
48
-        await salesService.updateSalesService(validatedData, id, req);
49
-        return messageSuccessResponse(res, 'Success update sales');
50
-    } catch (err) {
51
-        return errorResponse(res, err);
52
-    }
53
-}
54
-
55
-exports.deleteSales = async (req, res) => {
56
-    try {
57
-        const id = req.params.id;
58
-        await salesService.deleteSalesService(id, req);
59
-        return messageSuccessResponse(res, 'Success delete sales');
60
-    } catch (err) {
61
-        return errorResponse(res, err);
62
-    }
63
-};

+ 0 - 29
src/controllers/admin/StatusHistoryController.js

@@ -1,29 +0,0 @@
1
-const { PaginationParam } = require("../../utils/PaginationParams");
2
-const statusHistoryService = require('../../services/admin/StatusHistoryService.js');
3
-const { validateCreateStatusHisotryRequest } = require("../../validators/admin/status_history/StatusHistoryValidators.js");
4
-const { StatusHistoryCollection } = require("../../resources/admin/status_history/StatusHistoryCollection.js");
5
-const { errorResponse, messageSuccessResponse } = require("../../utils/Response.js");
6
-
7
-exports.getAllStatusHistory = async (req, res) => {
8
-    try {
9
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
10
-
11
-        const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService({
12
-            page, limit, search, sortBy, orderBy
13
-        }, req);
14
-
15
-        return StatusHistoryCollection({ req, res, data: status_histories, total, page, limit, message: 'Status history successfully retrieved' });
16
-    } catch (err) {
17
-        return errorResponse(res, err);
18
-    }
19
-};
20
-
21
-exports.storeStatusHistory = async (req, res) => {
22
-    try {
23
-        const validatedData = validateCreateStatusHisotryRequest(req.body);
24
-        await statusHistoryService.storeStatusHistoryService(validatedData, req);
25
-        return messageSuccessResponse(res, 'Success added status history', 201);
26
-    } catch (err) {
27
-        return errorResponse(res, err);
28
-    }
29
-}

+ 71 - 0
src/controllers/admin/StatusHistoryController.ts

@@ -0,0 +1,71 @@
1
+import { Request, Response } from 'express';
2
+import { PaginationParam } from '../../utils/PaginationParams';
3
+import * as statusHistoryService from '../../services/admin/StatusHistoryService';
4
+import { validateCreateStatusHisotryRequest } from '../../validators/admin/status_history/StatusHistoryValidators';
5
+import { StatusHistoryCollection } from '../../resources/admin/status_history/StatusHistoryCollection';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { CustomRequest } from '../../types/token/CustomRequest';
8
+
9
+export const getAllStatusHistory = async (req: Request, res: Response): Promise<Response> => {
10
+    try {
11
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
12
+
13
+        const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService(
14
+            { page, limit, search, sortBy, orderBy },
15
+            req
16
+        );
17
+
18
+        return StatusHistoryCollection(
19
+            req,
20
+            res,
21
+            status_histories,
22
+            total,
23
+            page,
24
+            limit,
25
+            'Status history successfully retrieved',
26
+        );
27
+    } catch (err) {
28
+        return errorResponse(res, err);
29
+    }
30
+};
31
+
32
+export const storeStatusHistory = async (req: Request, res: Response): Promise<Response> => {
33
+    try {
34
+        const validatedData = validateCreateStatusHisotryRequest(req.body);
35
+        await statusHistoryService.storeStatusHistoryService(validatedData, req as CustomRequest);
36
+        return messageSuccessResponse(res, 'Success added status history', 201);
37
+    } catch (err) {
38
+        return errorResponse(res, err);
39
+    }
40
+};
41
+
42
+
43
+// const { PaginationParam } = require("../../utils/PaginationParams");
44
+// const statusHistoryService = require('../../services/admin/StatusHistoryService.js');
45
+// const { validateCreateStatusHisotryRequest } = require("../../validators/admin/status_history/StatusHistoryValidators.js");
46
+// const { StatusHistoryCollection } = require("../../resources/admin/status_history/StatusHistoryCollection.js");
47
+// const { errorResponse, messageSuccessResponse } = require("../../utils/Response.js");
48
+
49
+// exports.getAllStatusHistory = async (req, res) => {
50
+//     try {
51
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
52
+
53
+//         const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService({
54
+//             page, limit, search, sortBy, orderBy
55
+//         }, req);
56
+
57
+//         return StatusHistoryCollection({ req, res, data: status_histories, total, page, limit, message: 'Status history successfully retrieved' });
58
+//     } catch (err) {
59
+//         return errorResponse(res, err);
60
+//     }
61
+// };
62
+
63
+// exports.storeStatusHistory = async (req, res) => {
64
+//     try {
65
+//         const validatedData = validateCreateStatusHisotryRequest(req.body);
66
+//         await statusHistoryService.storeStatusHistoryService(validatedData, req);
67
+//         return messageSuccessResponse(res, 'Success added status history', 201);
68
+//     } catch (err) {
69
+//         return errorResponse(res, err);
70
+//     }
71
+// }

+ 0 - 61
src/controllers/admin/VendorController.js

@@ -1,61 +0,0 @@
1
-const { VendorCollection } = require('../../resources/admin/vendor/VendorCollection.js');
2
-const { VendorResource } = require('../../resources/admin/vendor/VendorResource.js');
3
-const vendorService = require('../../services/admin/VendorService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreVendorRequest, validateUpdateVendorRequest } = require('../../validators/admin/vendor/VendorValidators.js');
7
-
8
-exports.getAllVendor = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { vendors, total } = await vendorService.getAllVendorService({
13
-            page, limit, search, sortBy, orderBy
14
-        });
15
-
16
-        return VendorCollection({ req, res, data: vendors, total, page, limit, message: 'Vendor data successfully retrieved' });
17
-    } catch (err) {
18
-        return errorResponse(res, err);
19
-    }
20
-};
21
-
22
-exports.showVendor = async (req, res) => {
23
-    try {
24
-        const id = req.params.id;
25
-        const { vendor, userName } = await vendorService.showVendorService(id);
26
-        return VendorResource(res, vendor, userName, 'Success show vendor');
27
-    } catch (err) {
28
-        return errorResponse(res, err);
29
-    }
30
-};
31
-
32
-exports.storeVendor = async (req, res) => {
33
-    try {
34
-        const validatedData = validateStoreVendorRequest(req.body);
35
-        await vendorService.storeVendorService(validatedData, req);
36
-        return messageSuccessResponse(res, 'Success added vendor', 201);
37
-    } catch (err) {
38
-        return errorResponse(res, err);
39
-    }
40
-}
41
-
42
-exports.updateVendor = async (req, res) => {
43
-    try {
44
-        const id = req.params.id;
45
-        const validatedData = validateUpdateVendorRequest(req.body);
46
-        await vendorService.updateVendorService(validatedData, id, req);
47
-        return messageSuccessResponse(res, 'Success update vendor');
48
-    } catch (err) {
49
-        return errorResponse(res, err);
50
-    }
51
-}
52
-
53
-exports.deleteVendor = async (req, res) => {
54
-    try {
55
-        const id = req.params.id;
56
-        await vendorService.deleteVendorService(id, req);
57
-        return messageSuccessResponse(res, 'Success delete vendor');
58
-    } catch (err) {
59
-        return errorResponse(res, err);
60
-    }
61
-};

+ 126 - 0
src/controllers/admin/VendorController.ts

@@ -0,0 +1,126 @@
1
+import { Request, Response } from 'express';
2
+import { VendorCollection } from '../../resources/admin/vendor/VendorCollection';
3
+import { VendorResource } from '../../resources/admin/vendor/VendorResource';
4
+import * as VendorService from '../../services/admin/VendorService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreVendorRequest, validateUpdateVendorRequest } from '../../validators/admin/vendor/VendorValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllVendor = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
13
+
14
+        const { vendors, total } = await VendorService.getAllVendorService({
15
+            page, limit, search, sortBy, orderBy
16
+        });
17
+
18
+        return VendorCollection(req, res, vendors, total, page, limit, 'Vendor data successfully retrieved');
19
+    } catch (err) {
20
+        return errorResponse(res, err);
21
+    }
22
+};
23
+
24
+export const showVendor = async (req: Request, res: Response): Promise<Response> => {
25
+    try {
26
+        const id: string = req.params.id;
27
+        const { vendor } = await VendorService.showVendorService(id);
28
+        return VendorResource(res, vendor, 'Success show vendor');
29
+    } catch (err) {
30
+        return errorResponse(res, err);
31
+    }
32
+};
33
+
34
+export const storeVendor = async (req: Request, res: Response): Promise<Response> => {
35
+    try {
36
+        const validatedData = validateStoreVendorRequest(req.body);
37
+        await VendorService.storeVendorService(validatedData, req as CustomRequest);
38
+        return messageSuccessResponse(res, 'Success added vendor', 201);
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const updateVendor = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const id: string = req.params.id;
47
+        const validatedData = validateUpdateVendorRequest(req.body);
48
+        await VendorService.updateVendorService(validatedData, id, req as CustomRequest);
49
+        return messageSuccessResponse(res, 'Success update vendor');
50
+    } catch (err) {
51
+        return errorResponse(res, err);
52
+    }
53
+};
54
+
55
+export const deleteVendor = async (req: Request, res: Response): Promise<Response> => {
56
+    try {
57
+        const id: string = req.params.id;
58
+        await VendorService.deleteVendorService(id, req as CustomRequest);
59
+        return messageSuccessResponse(res, 'Success delete vendor');
60
+    } catch (err) {
61
+        return errorResponse(res, err);
62
+    }
63
+};
64
+
65
+
66
+// const { VendorCollection } = require('../../resources/admin/vendor/VendorCollection.js');
67
+// const { VendorResource } = require('../../resources/admin/vendor/VendorResource.js');
68
+// const vendorService = require('../../services/admin/VendorService.js');
69
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
70
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
71
+// const { validateStoreVendorRequest, validateUpdateVendorRequest } = require('../../validators/admin/vendor/VendorValidators.js');
72
+
73
+// exports.getAllVendor = async (req, res) => {
74
+//     try {
75
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
76
+
77
+//         const { vendors, total } = await vendorService.getAllVendorService({
78
+//             page, limit, search, sortBy, orderBy
79
+//         });
80
+
81
+//         return VendorCollection({ req, res, data: vendors, total, page, limit, message: 'Vendor data successfully retrieved' });
82
+//     } catch (err) {
83
+//         return errorResponse(res, err);
84
+//     }
85
+// };
86
+
87
+// exports.showVendor = async (req, res) => {
88
+//     try {
89
+//         const id = req.params.id;
90
+//         const { vendor } = await vendorService.showVendorService(id);
91
+//         return VendorResource(res, vendor, 'Success show vendor');
92
+//     } catch (err) {
93
+//         return errorResponse(res, err);
94
+//     }
95
+// };
96
+
97
+// exports.storeVendor = async (req, res) => {
98
+//     try {
99
+//         const validatedData = validateStoreVendorRequest(req.body);
100
+//         await vendorService.storeVendorService(validatedData, req);
101
+//         return messageSuccessResponse(res, 'Success added vendor', 201);
102
+//     } catch (err) {
103
+//         return errorResponse(res, err);
104
+//     }
105
+// }
106
+
107
+// exports.updateVendor = async (req, res) => {
108
+//     try {
109
+//         const id = req.params.id;
110
+//         const validatedData = validateUpdateVendorRequest(req.body);
111
+//         await vendorService.updateVendorService(validatedData, id, req);
112
+//         return messageSuccessResponse(res, 'Success update vendor');
113
+//     } catch (err) {
114
+//         return errorResponse(res, err);
115
+//     }
116
+// }
117
+
118
+// exports.deleteVendor = async (req, res) => {
119
+//     try {
120
+//         const id = req.params.id;
121
+//         await vendorService.deleteVendorService(id, req);
122
+//         return messageSuccessResponse(res, 'Success delete vendor');
123
+//     } catch (err) {
124
+//         return errorResponse(res, err);
125
+//     }
126
+// };

+ 0 - 59
src/controllers/admin/VendorExperienceController.js

@@ -1,59 +0,0 @@
1
-const { VendorHistoriCollection } = require('../../resources/admin/vendor_history/VendorExperienceCollection.js');
2
-const { VendorHistoriResource } = require('../../resources/admin/vendor_history/VendorExperienceResource.js');
3
-const vendorHistoryService = require('../../services/admin/VendorExperienceService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreVendorHistoryRequest, validateUpdateVendorHistoryRequest } = require('../../validators/admin/vendor_experience/VendorExperienceValidators.js');
7
-
8
-exports.getAllVendorHistory = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { vendor_histories, total } = await vendorHistoryService.getAllVendorHistoryService({
13
-            page, limit, search, sortBy, orderBy
14
-        }, req);
15
-
16
-        return VendorHistoriCollection(req, res, vendor_histories, total, page, limit, 'Vendor history successfully retrieved');
17
-
18
-    } catch (err) {
19
-        return errorResponse(res, err);
20
-    }
21
-};
22
-
23
-exports.showVendorHistory = async (req, res) => {
24
-    try {
25
-        const data = await vendorHistoryService.showVendorHistoryService(req);
26
-        return VendorHistoriResource(res, data, 'Success show vendor history');
27
-    } catch (err) {
28
-        return errorResponse(res, err);
29
-    }
30
-};
31
-
32
-exports.storeVendorHistory = async (req, res) => {
33
-    try {
34
-        const validatedData = validateStoreVendorHistoryRequest(req.body);
35
-        await vendorHistoryService.storeVendorHistoryService(validatedData, req);
36
-        return messageSuccessResponse(res, 'Success added vendor history', 201);
37
-    } catch (err) {
38
-        return errorResponse(res, err);
39
-    }
40
-}
41
-
42
-exports.updateVendorHistory = async (req, res) => {
43
-    try {
44
-        const validatedData = validateUpdateVendorHistoryRequest(req.body);
45
-        await vendorHistoryService.updateVendorHistoryService(validatedData, req);
46
-        return messageSuccessResponse(res, 'Success update vendor history');
47
-    } catch (err) {
48
-        return errorResponse(res, err);
49
-    }
50
-}
51
-
52
-exports.deleteVendorHistory = async (req, res) => {
53
-    try {
54
-        await vendorHistoryService.deleteVendorHistoryService(req);
55
-        return messageSuccessResponse(res, 'Success delete vendor history');
56
-    } catch (err) {
57
-        return errorResponse(res, err);
58
-    }
59
-};

+ 122 - 0
src/controllers/admin/VendorExperienceController.ts

@@ -0,0 +1,122 @@
1
+import { Request, Response } from 'express';
2
+import { VendorExperienceCollection } from '../../resources/admin/vendor_experience/VendorExperienceCollection';
3
+import { VendorExperienceResource } from '../../resources/admin/vendor_experience/VendorExperienceResource';
4
+import * as VendorExperienceService from '../../services/admin/VendorExperienceService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreVendorExperienceRequest, validateUpdateVendorExperienceRequest } from '../../validators/admin/vendor_experience/VendorExperienceValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllVendorExperience = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
13
+
14
+        const { vendor_experiences, total } = await VendorExperienceService.getAllVendorExperienceService(
15
+            { page, limit, search, sortBy, orderBy },
16
+            req
17
+        );
18
+
19
+        return VendorExperienceCollection(req, res, vendor_experiences, total, page, limit, 'Vendor experience successfully retrieved');
20
+    } catch (err) {
21
+        return errorResponse(res, err);
22
+    }
23
+};
24
+
25
+export const showVendorExperience = async (req: Request, res: Response) => {
26
+    try {
27
+        const data = await VendorExperienceService.showVendorExperienceService(req);
28
+        return VendorExperienceResource(res, data, 'Success show vendor experience');
29
+    } catch (err) {
30
+        return errorResponse(res, err);
31
+    }
32
+};
33
+
34
+export const storeVendorExperience = async (req: Request, res: Response): Promise<Response> => {
35
+    try {
36
+        const validatedData = validateStoreVendorExperienceRequest(req.body);
37
+        await VendorExperienceService.storeVendorExperienceService(validatedData, req as CustomRequest);
38
+        return messageSuccessResponse(res, 'Success added vendor experience', 201);
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const updateVendorExperience = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const validatedData = validateUpdateVendorExperienceRequest(req.body);
47
+        await VendorExperienceService.updateVendorExperienceService(validatedData, req as CustomRequest);
48
+        return messageSuccessResponse(res, 'Success update vendor experience');
49
+    } catch (err) {
50
+        return errorResponse(res, err);
51
+    }
52
+};
53
+
54
+export const deleteVendorExperience = async (req: Request, res: Response): Promise<Response> => {
55
+    try {
56
+        await VendorExperienceService.deleteVendorExperienceService(req as CustomRequest);
57
+        return messageSuccessResponse(res, 'Success delete vendor experience');
58
+    } catch (err) {
59
+        return errorResponse(res, err);
60
+    }
61
+};
62
+
63
+
64
+// const { VendorExperienceCollection } = require('../../resources/admin/vendor_experience/VendorExperienceCollection.js');
65
+// const { VendorExperienceResource } = require('../../resources/admin/vendor_experience/VendorExperienceResource.js');
66
+// const vendorHistoryService = require('../../services/admin/VendorExperienceService.js');
67
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
68
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
69
+// const { validateStoreVendorHistoryRequest, validateUpdateVendorHistoryRequest } = require('../../validators/admin/vendor_experience/VendorExperienceValidators.js');
70
+
71
+// exports.getAllVendorHistory = async (req, res) => {
72
+//     try {
73
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
74
+
75
+//         const { vendor_histories, total } = await vendorHistoryService.getAllVendorHistoryService({
76
+//             page, limit, search, sortBy, orderBy
77
+//         }, req);
78
+
79
+//         return VendorExperienceCollection(req, res, vendor_histories, total, page, limit, 'Vendor experience successfully retrieved');
80
+
81
+//     } catch (err) {
82
+//         return errorResponse(res, err);
83
+//     }
84
+// };
85
+
86
+// exports.showVendorHistory = async (req, res) => {
87
+//     try {
88
+//         const data = await vendorHistoryService.showVendorHistoryService(req);
89
+//         return VendorExperienceResource(res, data, 'Success show vendor experience');
90
+//     } catch (err) {
91
+//         return errorResponse(res, err);
92
+//     }
93
+// };
94
+
95
+// exports.storeVendorHistory = async (req, res) => {
96
+//     try {
97
+//         const validatedData = validateStoreVendorHistoryRequest(req.body);
98
+//         await vendorHistoryService.storeVendorHistoryService(validatedData, req);
99
+//         return messageSuccessResponse(res, 'Success added vendor experience', 201);
100
+//     } catch (err) {
101
+//         return errorResponse(res, err);
102
+//     }
103
+// }
104
+
105
+// exports.updateVendorHistory = async (req, res) => {
106
+//     try {
107
+//         const validatedData = validateUpdateVendorHistoryRequest(req.body);
108
+//         await vendorHistoryService.updateVendorHistoryService(validatedData, req);
109
+//         return messageSuccessResponse(res, 'Success update vendor experience');
110
+//     } catch (err) {
111
+//         return errorResponse(res, err);
112
+//     }
113
+// }
114
+
115
+// exports.deleteVendorHistory = async (req, res) => {
116
+//     try {
117
+//         await vendorHistoryService.deleteVendorHistoryService(req);
118
+//         return messageSuccessResponse(res, 'Success delete vendor experience');
119
+//     } catch (err) {
120
+//         return errorResponse(res, err);
121
+//     }
122
+// };

+ 0 - 33
src/controllers/auth/AuthControllers.js

@@ -1,33 +0,0 @@
1
-const { LoginResource } = require('../../resources/auth/LoginResource.js');
2
-const { UserResource } = require('../../resources/auth/UserResource.js');
3
-const { loginService, getUserService, logoutService } = require('../../services/auth/AuthService.js');
4
-const { successResponse, errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
5
-const { validateLoginRequest } = require('../../validators/auth/LoginValidators.js');
6
-
7
-exports.login = async (req, res) => {
8
-    try {
9
-        const validated = validateLoginRequest(req.body);
10
-        const data = await loginService(validated, req);
11
-        return LoginResource(res, data, "Login success")
12
-    } catch (error) {
13
-        return errorResponse(res, error);
14
-    }
15
-};
16
-
17
-exports.getUser = async (req, res) => {
18
-    try {
19
-        const data = await getUserService(req);
20
-        return UserResource(res, data, 'Success get user');
21
-    } catch (error) {
22
-        return errorResponse(res, error);
23
-    }
24
-};
25
-
26
-exports.logout = async (req, res) => {
27
-    try {
28
-        await logoutService(req);
29
-        return messageSuccessResponse(res, 'Logout success', 200);
30
-    } catch (error) {
31
-        return errorResponse(res, error);
32
-    }
33
-}

+ 0 - 16
src/controllers/sales/AreaController.js

@@ -1,16 +0,0 @@
1
-const { UserAreaCollection } = require("../../resources/sales/area/UserAreaCollection.js");
2
-const { getAllAreaByUserService } = require("../../services/sales/AreaService.js");
3
-const { PaginationParam } = require("../../utils/PaginationParams");
4
-const { errorResponse } = require("../../utils/Response");
5
-
6
-exports.getAllAreaByUser = async (req, res) => {
7
-    try {
8
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
9
-
10
-        const { areas, total } = await getAllAreaByUserService({ page, limit, search, sortBy, orderBy }, req);
11
-
12
-        return UserAreaCollection({ req, res, data: areas, total, page, limit, message: 'Area data successfully retrieved' });
13
-    } catch (err) {
14
-        return errorResponse(res, err);
15
-    }
16
-};

+ 38 - 0
src/controllers/sales/AreaController.ts

@@ -0,0 +1,38 @@
1
+import { Request, Response } from 'express';
2
+import { UserAreaCollection } from '../../resources/sales/area/UserAreaCollection';
3
+import { getAllAreaByUserService } from '../../services/sales/AreaService';
4
+import { PaginationParam } from '../../utils/PaginationParams';
5
+import { errorResponse } from '../../utils/Response';
6
+import { CustomRequest } from '../../types/token/CustomRequest';
7
+
8
+export const getAllAreaByUser = async (req: Request, res: Response): Promise<Response | void> => {
9
+    try {
10
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
+
12
+        const { areas, total } = await getAllAreaByUserService(
13
+            { page, limit, search, sortBy, orderBy },
14
+            req as CustomRequest
15
+        );
16
+
17
+        return UserAreaCollection(req, res, areas, total, page, limit, 'Area data successfully retrieved',);
18
+    } catch (err) {
19
+        return errorResponse(res, err);
20
+    }
21
+};
22
+
23
+// const { UserAreaCollection } = require("../../resources/sales/area/UserAreaCollection.js");
24
+// const { getAllAreaByUserService } = require("../../services/sales/AreaService.js");
25
+// const { PaginationParam } = require("../../utils/PaginationParams");
26
+// const { errorResponse } = require("../../utils/Response");
27
+
28
+// exports.getAllAreaByUser = async (req, res) => {
29
+//     try {
30
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
31
+
32
+//         const { areas, total } = await getAllAreaByUserService({ page, limit, search, sortBy, orderBy }, req);
33
+
34
+//         return UserAreaCollection({ req, res, data: areas, total, page, limit, message: 'Area data successfully retrieved' });
35
+//     } catch (err) {
36
+//         return errorResponse(res, err);
37
+//     }
38
+// };

+ 0 - 58
src/controllers/sales/ExecutivesHistoryController.js

@@ -1,58 +0,0 @@
1
-const { ExecutivesHistoriResource } = require('../../resources/sales/executives_history/ExecutivesHistoriResource.js');
2
-const { ExecutivesHistoriCollection } = require('../../resources/sales/executives_history/ExecutivesHistoriCollection.js');
3
-const executivesHistoryService = require('../../services/sales/ExecutivesHistoryService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest } = require('../../validators/sales/executives_history/ExecutivesHistoriValidators.js');
7
-
8
-exports.getAllExecutivesHistory = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService({
13
-            page, limit, search, sortBy, orderBy
14
-        }, req);
15
-
16
-        return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
17
-    } catch (err) {
18
-        return errorResponse(res, err);
19
-    }
20
-};
21
-
22
-exports.showExecutivesHistory = async (req, res) => {
23
-    try {
24
-        const data = await executivesHistoryService.showExecutivesHistoryService(req);
25
-        return ExecutivesHistoriResource(res, data, 'Success show executives history');
26
-    } catch (err) {
27
-        return errorResponse(res, err);
28
-    }
29
-};
30
-
31
-exports.storeExecutivesHistory = async (req, res) => {
32
-    try {
33
-        const validatedData = validateStoreExecutivesHistoryRequest(req.body);
34
-        await executivesHistoryService.storeExecutivesHistoryService(validatedData, req);
35
-        return messageSuccessResponse(res, 'Success added executives history', 201);
36
-    } catch (err) {
37
-        return errorResponse(res, err);
38
-    }
39
-}
40
-
41
-exports.updateExecutivesHistory = async (req, res) => {
42
-    try {
43
-        const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
44
-        await executivesHistoryService.updateExecutivesHistoryService(validatedData, req);
45
-        return messageSuccessResponse(res, 'Success update executives history');
46
-    } catch (err) {
47
-        return errorResponse(res, err);
48
-    }
49
-}
50
-
51
-exports.deleteExecutivesHistory = async (req, res) => {
52
-    try {
53
-        await executivesHistoryService.deleteExecutivesHistoryService(req);
54
-        return messageSuccessResponse(res, 'Success delete executives history');
55
-    } catch (err) {
56
-        return errorResponse(res, err);
57
-    }
58
-};

+ 120 - 0
src/controllers/sales/ExecutivesHistoryController.ts

@@ -0,0 +1,120 @@
1
+import { Request, Response } from 'express';
2
+import { ExecutivesHistoriCollection } from '../../resources/sales/executives_history/ExecutivesHistoriCollection';
3
+import { ExecutivesHistoriResource } from '../../resources/sales/executives_history/ExecutivesHistoriResource';
4
+import * as executivesHistoryService from '../../services/sales/ExecutivesHistoryService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest, } from '../../validators/sales/executives_history/ExecutivesHistoriValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
13
+
14
+        const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService(
15
+            { page, limit, search, sortBy, orderBy },
16
+            req as CustomRequest
17
+        );
18
+
19
+        return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
20
+    } catch (err) {
21
+        return errorResponse(res, err);
22
+    }
23
+};
24
+
25
+export const showExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
26
+    try {
27
+        const data = await executivesHistoryService.showExecutivesHistoryService(req as CustomRequest);
28
+        return ExecutivesHistoriResource(res, data, 'Success show executives history');
29
+    } catch (err) {
30
+        return errorResponse(res, err);
31
+    }
32
+};
33
+
34
+export const storeExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
35
+    try {
36
+        const validatedData = validateStoreExecutivesHistoryRequest(req.body);
37
+        await executivesHistoryService.storeExecutivesHistoryService(validatedData, req as CustomRequest);
38
+        return messageSuccessResponse(res, 'Success added executives history', 201);
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const updateExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
47
+        await executivesHistoryService.updateExecutivesHistoryService(validatedData, req as CustomRequest);
48
+        return messageSuccessResponse(res, 'Success update executives history');
49
+    } catch (err) {
50
+        return errorResponse(res, err);
51
+    }
52
+};
53
+
54
+export const deleteExecutivesHistory = async (req: Request, res: Response): Promise<Response> => {
55
+    try {
56
+        await executivesHistoryService.deleteExecutivesHistoryService(req as CustomRequest);
57
+        return messageSuccessResponse(res, 'Success delete executives history');
58
+    } catch (err) {
59
+        return errorResponse(res, err);
60
+    }
61
+};
62
+
63
+// const { ExecutivesHistoriResource } = require('../../resources/sales/executives_history/ExecutivesHistoriResource.js');
64
+// const { ExecutivesHistoriCollection } = require('../../resources/sales/executives_history/ExecutivesHistoriCollection.js');
65
+// const executivesHistoryService = require('../../services/sales/ExecutivesHistoryService.js');
66
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
67
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
68
+// const { validateStoreExecutivesHistoryRequest, validateUpdateExecutivesHistoryRequest } = require('../../validators/sales/executives_history/ExecutivesHistoriValidators.js');
69
+
70
+// exports.getAllExecutivesHistory = async (req, res) => {
71
+//     try {
72
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
73
+
74
+//         const { executives_histories, total } = await executivesHistoryService.getAllExecutivesHistoryService({
75
+//             page, limit, search, sortBy, orderBy
76
+//         }, req);
77
+
78
+//         return ExecutivesHistoriCollection(req, res, executives_histories, total, page, limit, 'Executives history successfully retrieved');
79
+//     } catch (err) {
80
+//         return errorResponse(res, err);
81
+//     }
82
+// };
83
+
84
+// exports.showExecutivesHistory = async (req, res) => {
85
+//     try {
86
+//         const data = await executivesHistoryService.showExecutivesHistoryService(req);
87
+//         return ExecutivesHistoriResource(res, data, 'Success show executives history');
88
+//     } catch (err) {
89
+//         return errorResponse(res, err);
90
+//     }
91
+// };
92
+
93
+// exports.storeExecutivesHistory = async (req, res) => {
94
+//     try {
95
+//         const validatedData = validateStoreExecutivesHistoryRequest(req.body);
96
+//         await executivesHistoryService.storeExecutivesHistoryService(validatedData, req);
97
+//         return messageSuccessResponse(res, 'Success added executives history', 201);
98
+//     } catch (err) {
99
+//         return errorResponse(res, err);
100
+//     }
101
+// }
102
+
103
+// exports.updateExecutivesHistory = async (req, res) => {
104
+//     try {
105
+//         const validatedData = validateUpdateExecutivesHistoryRequest(req.body);
106
+//         await executivesHistoryService.updateExecutivesHistoryService(validatedData, req);
107
+//         return messageSuccessResponse(res, 'Success update executives history');
108
+//     } catch (err) {
109
+//         return errorResponse(res, err);
110
+//     }
111
+// }
112
+
113
+// exports.deleteExecutivesHistory = async (req, res) => {
114
+//     try {
115
+//         await executivesHistoryService.deleteExecutivesHistoryService(req);
116
+//         return messageSuccessResponse(res, 'Success delete executives history');
117
+//     } catch (err) {
118
+//         return errorResponse(res, err);
119
+//     }
120
+// };

+ 0 - 49
src/controllers/sales/HospitalController.js

@@ -1,49 +0,0 @@
1
-const { HospitalCollection } = require("../../resources/sales/hospital/HospitalCollection.js");
2
-const { HospitalResource } = require("../../resources/sales/hospital/HospitalResource.js");
3
-const { getAllHospitalByAreaService, storeHospitalService, updateHospitalService, showHospitalService } = require("../../services/sales/HospitalService");
4
-const { PaginationParam } = require("../../utils/PaginationParams");
5
-const { errorResponse, messageSuccessResponse } = require("../../utils/Response");
6
-const { validateStoreHospitalRequest, validateUpdateHospitalRequest } = require('../../validators/admin/hospital/HospitalValidators.js');
7
-
8
-exports.getAllHospitalByArea = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status } = PaginationParam(req, ['province', 'city', 'type', 'ownership', 'progress_status']);
11
-
12
-        const { hospitals, total } = await getAllHospitalByAreaService({ page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status }, req);
13
-
14
-        return HospitalCollection({ req, res, data: hospitals, total, page, limit, message: 'Hospital data successfully retrieved' });
15
-    } catch (err) {
16
-        return errorResponse(res, err);
17
-    }
18
-};
19
-
20
-exports.storeHospital = async (req, res) => {
21
-    try {
22
-        const validatedData = validateStoreHospitalRequest(req.body);
23
-        await storeHospitalService(validatedData, req);
24
-        return messageSuccessResponse(res, 'Success added hospital', 201);
25
-    } catch (err) {
26
-        return errorResponse(res, err);
27
-    }
28
-}
29
-
30
-exports.updateHospital = async (req, res) => {
31
-    try {
32
-        const id = req.params.id;
33
-        const validatedData = validateUpdateHospitalRequest(req.body);
34
-        await updateHospitalService(validatedData, id, req);
35
-        return messageSuccessResponse(res, 'Success update hospital');
36
-    } catch (err) {
37
-        return errorResponse(res, err);
38
-    }
39
-}
40
-
41
-exports.showHospital = async (req, res) => {
42
-    try {
43
-        const id = req.params.id;
44
-        const { hospital, userName } = await showHospitalService(id);
45
-        return HospitalResource(res, hospital, userName, 'Success show hospital');
46
-    } catch (err) {
47
-        return errorResponse(res, err);
48
-    }
49
-};

+ 110 - 0
src/controllers/sales/HospitalController.ts

@@ -0,0 +1,110 @@
1
+import { Request, Response } from "express";
2
+import { HospitalCollection } from "../../resources/sales/hospital/HospitalCollection";
3
+import { HospitalResource } from "../../resources/sales/hospital/HospitalResource";
4
+import * as HospitalController from "../../services/sales/HospitalService";
5
+import { PaginationParam } from "../../utils/PaginationParams";
6
+import { errorResponse, messageSuccessResponse } from "../../utils/Response";
7
+import { validateStoreHospitalRequest, validateUpdateHospitalRequest, } from "../../validators/admin/hospital/HospitalValidators";
8
+import { CustomRequest } from "../../types/token/CustomRequest";
9
+
10
+// GET All Hospital by Area
11
+export const getAllHospitalByArea = async (req: any, res: Response): Promise<Response> => {
12
+    try {
13
+        const { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status } =
14
+            PaginationParam(req, ["province", "city", "type", "ownership", "progress_status"]);
15
+
16
+        const { hospitals, total } = await HospitalController.getAllHospitalByAreaService(
17
+            { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status },
18
+            req
19
+        );
20
+
21
+        return HospitalCollection({ req, res, data: hospitals, total, page, limit, message: "Hospital data successfully retrieved" });
22
+    } catch (err) {
23
+        return errorResponse(res, err);
24
+    }
25
+};
26
+
27
+// POST Store Hospital
28
+export const storeHospital = async (req: Request, res: Response): Promise<Response> => {
29
+    try {
30
+        const validatedData = validateStoreHospitalRequest(req.body);
31
+        await HospitalController.storeHospitalService(validatedData, req as CustomRequest);
32
+        return messageSuccessResponse(res, "Success added hospital", 201);
33
+    } catch (err) {
34
+        return errorResponse(res, err);
35
+    }
36
+};
37
+
38
+// PATCH/PUT Update Hospital
39
+export const updateHospital = async (req: Request, res: Response): Promise<Response> => {
40
+    try {
41
+        const id = req.params.id;
42
+        const validatedData = validateUpdateHospitalRequest(req.body);
43
+        await HospitalController.updateHospitalService(validatedData, id, req as CustomRequest);
44
+        return messageSuccessResponse(res, "Success update hospital");
45
+    } catch (err) {
46
+        return errorResponse(res, err);
47
+    }
48
+};
49
+
50
+// GET Show Hospital by ID
51
+export const showHospital = async (req: Request, res: Response): Promise<Response> => {
52
+    try {
53
+        const id = req.params.id;
54
+        const { hospital } = await HospitalController.showHospitalService(id, req as CustomRequest);
55
+        return HospitalResource(res, hospital, "Success show hospital");
56
+    } catch (err) {
57
+        return errorResponse(res, err);
58
+    }
59
+};
60
+
61
+
62
+// const { HospitalCollection } = require("../../resources/sales/hospital/HospitalCollection.js");
63
+// const { HospitalResource } = require("../../resources/sales/hospital/HospitalResource.js");
64
+// const { getAllHospitalByAreaService, storeHospitalService, updateHospitalService, showHospitalService } = require("../../services/sales/HospitalService");
65
+// const { PaginationParam } = require("../../utils/PaginationParams");
66
+// const { errorResponse, messageSuccessResponse } = require("../../utils/Response");
67
+// const { validateStoreHospitalRequest, validateUpdateHospitalRequest } = require('../../validators/admin/hospital/HospitalValidators.js');
68
+
69
+// exports.getAllHospitalByArea = async (req, res) => {
70
+//     try {
71
+//         const { page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status } = PaginationParam(req, ['province', 'city', 'type', 'ownership', 'progress_status']);
72
+
73
+//         const { hospitals, total } = await getAllHospitalByAreaService({ page, limit, search, sortBy, orderBy, province, city, type, ownership, progress_status }, req);
74
+
75
+//         return HospitalCollection({ req, res, data: hospitals, total, page, limit, message: 'Hospital data successfully retrieved' });
76
+//     } catch (err) {
77
+//         return errorResponse(res, err);
78
+//     }
79
+// };
80
+
81
+// exports.storeHospital = async (req, res) => {
82
+//     try {
83
+//         const validatedData = validateStoreHospitalRequest(req.body);
84
+//         await storeHospitalService(validatedData, req);
85
+//         return messageSuccessResponse(res, 'Success added hospital', 201);
86
+//     } catch (err) {
87
+//         return errorResponse(res, err);
88
+//     }
89
+// }
90
+
91
+// exports.updateHospital = async (req, res) => {
92
+//     try {
93
+//         const id = req.params.id;
94
+//         const validatedData = validateUpdateHospitalRequest(req.body);
95
+//         await updateHospitalService(validatedData, id, req);
96
+//         return messageSuccessResponse(res, 'Success update hospital');
97
+//     } catch (err) {
98
+//         return errorResponse(res, err);
99
+//     }
100
+// }
101
+
102
+// exports.showHospital = async (req, res) => {
103
+//     try {
104
+//         const id = req.params.id;
105
+//         const { hospital } = await showHospitalService(id);
106
+//         return HospitalResource(res, hospital, 'Success show hospital');
107
+//     } catch (err) {
108
+//         return errorResponse(res, err);
109
+//     }
110
+// };

+ 0 - 29
src/controllers/sales/StatusHistoryController.js

@@ -1,29 +0,0 @@
1
-const { PaginationParam } = require("../../utils/PaginationParams");
2
-const statusHistoryService = require('../../services/sales/StatusHistoryService.js');
3
-const { validateCreateStatusHisotryRequest } = require("../../validators/admin/status_history/StatusHistoryValidators.js");
4
-const { StatusHistoryCollection } = require("../../resources/sales/status_history/StatusHistoryCollection.js");
5
-const { errorResponse, messageSuccessResponse } = require("../../utils/Response.js");
6
-
7
-exports.getAllStatusHistory = async (req, res) => {
8
-    try {
9
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
10
-
11
-        const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService({
12
-            page, limit, search, sortBy, orderBy
13
-        }, req);
14
-
15
-        return StatusHistoryCollection({ req, res, data: status_histories, total, page, limit, message: 'Status history successfully retrieved' });
16
-    } catch (err) {
17
-        return errorResponse(res, err);
18
-    }
19
-};
20
-
21
-exports.storeStatusHistory = async (req, res) => {
22
-    try {
23
-        const validatedData = validateCreateStatusHisotryRequest(req.body);
24
-        await statusHistoryService.storeStatusHistoryService(validatedData, req);
25
-        return messageSuccessResponse(res, 'Success added status history', 201);
26
-    } catch (err) {
27
-        return errorResponse(res, err);
28
-    }
29
-}

+ 71 - 0
src/controllers/sales/StatusHistoryController.ts

@@ -0,0 +1,71 @@
1
+import { Request, Response } from 'express';
2
+import { PaginationParam } from '../../utils/PaginationParams';
3
+import * as statusHistoryService from '../../services/sales/StatusHistoryService';
4
+import { validateCreateStatusHisotryRequest } from '../../validators/sales/status_history/StatusHistoryValidators';
5
+import { StatusHistoryCollection } from '../../resources/sales/status_history/StatusHistoryCollection';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { CustomRequest } from '../../types/token/CustomRequest';
8
+
9
+export const getAllStatusHistory = async (req: Request, res: Response): Promise<Response> => {
10
+    try {
11
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
12
+
13
+        const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService(
14
+            { page, limit, search, sortBy, orderBy },
15
+            req as CustomRequest
16
+        );
17
+
18
+        return StatusHistoryCollection(
19
+            req,
20
+            res,
21
+            status_histories,
22
+            total,
23
+            page,
24
+            limit,
25
+            'Status history successfully retrieved',
26
+        );
27
+    } catch (err) {
28
+        return errorResponse(res, err);
29
+    }
30
+};
31
+
32
+export const storeStatusHistory = async (req: Request, res: Response): Promise<Response> => {
33
+    try {
34
+        const validatedData = validateCreateStatusHisotryRequest(req.body);
35
+        await statusHistoryService.storeStatusHistoryService(validatedData, req as CustomRequest);
36
+        return messageSuccessResponse(res, 'Success added status history', 201);
37
+    } catch (err) {
38
+        return errorResponse(res, err);
39
+    }
40
+};
41
+
42
+
43
+// const { PaginationParam } = require("../../utils/PaginationParams");
44
+// const statusHistoryService = require('../../services/sales/StatusHistoryService.js');
45
+// const { validateCreateStatusHisotryRequest } = require("../../validators/admin/status_history/StatusHistoryValidators.js");
46
+// const { StatusHistoryCollection } = require("../../resources/sales/status_history/StatusHistoryCollection.js");
47
+// const { errorResponse, messageSuccessResponse } = require("../../utils/Response.js");
48
+
49
+// exports.getAllStatusHistory = async (req, res) => {
50
+//     try {
51
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
52
+
53
+//         const { status_histories, total } = await statusHistoryService.getAllStatusHistoryService({
54
+//             page, limit, search, sortBy, orderBy
55
+//         }, req);
56
+
57
+//         return StatusHistoryCollection({ req, res, data: status_histories, total, page, limit, message: 'Status history successfully retrieved' });
58
+//     } catch (err) {
59
+//         return errorResponse(res, err);
60
+//     }
61
+// };
62
+
63
+// exports.storeStatusHistory = async (req, res) => {
64
+//     try {
65
+//         const validatedData = validateCreateStatusHisotryRequest(req.body);
66
+//         await statusHistoryService.storeStatusHistoryService(validatedData, req);
67
+//         return messageSuccessResponse(res, 'Success added status history', 201);
68
+//     } catch (err) {
69
+//         return errorResponse(res, err);
70
+//     }
71
+// }

+ 0 - 60
src/controllers/sales/VendorController.js

@@ -1,60 +0,0 @@
1
-const { VendorCollection } = require('../../resources/sales/vendor/VendorCollection.js');
2
-const vendorService = require('../../services/sales/VendorService.js');
3
-const { ListResponse } = require('../../utils/ListResponse.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, successResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-
7
-exports.getAllVendor = async (req, res) => {
8
-    try {
9
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
10
-
11
-        const { vendors, total } = await vendorService.getAllVendorService({
12
-            page, limit, search, sortBy, orderBy
13
-        }, req);
14
-
15
-        return VendorCollection(req, res, vendors, total, page, limit, 'Vendor data sales successfully retrieved');
16
-    } catch (err) {
17
-        return errorResponse(res, err);
18
-    }
19
-};
20
-
21
-// exports.showVendor = async (req, res) => {
22
-//     try {
23
-//         const id = req.params.id;
24
-//         const data = await vendorService.showVendorService(id);
25
-//         return successResponse(res, data, 'Success show vendor');
26
-//     } catch (err) {
27
-//         return errorResponse(res, err);
28
-//     }
29
-// };
30
-
31
-// exports.storeVendor = async (req, res) => {
32
-//     try {
33
-//         const validatedData = validateStoreVendorRequest(req.body);
34
-//         await vendorService.storeVendorService(validatedData, req);
35
-//         return messageSuccessResponse(res, 'Success added vendor', 201);
36
-//     } catch (err) {
37
-//         return errorResponse(res, err);
38
-//     }
39
-// }
40
-
41
-// exports.updateVendor = async (req, res) => {
42
-//     try {
43
-//         const id = req.params.id;
44
-//         const validatedData = validateStoreVendorRequest(req.body);
45
-//         await vendorService.updateVendorService(validatedData, id, req);
46
-//         return messageSuccessResponse(res, 'Success update vendor');
47
-//     } catch (err) {
48
-//         return errorResponse(res, err);
49
-//     }
50
-// }
51
-
52
-// exports.deleteVendor = async (req, res) => {
53
-//     try {
54
-//         const id = req.params.id;
55
-//         await vendorService.deleteVendorService(id, req);
56
-//         return messageSuccessResponse(res, 'Success delete vendor');
57
-//     } catch (err) {
58
-//         return errorResponse(res, err);
59
-//     }
60
-// };

+ 121 - 0
src/controllers/sales/VendorExperienceController.ts

@@ -0,0 +1,121 @@
1
+import { Request, Response } from 'express';
2
+import { VendorExperienceCollection } from '../../resources/sales/vendor_experience/VendorExperienceCollection';
3
+import { VendorExperienceResource } from '../../resources/sales/vendor_experience/VendorExperienceResource';
4
+import * as VendorExperienceService from '../../services/sales/VendorExperienceService';
5
+import { PaginationParam } from '../../utils/PaginationParams';
6
+import { errorResponse, messageSuccessResponse } from '../../utils/Response';
7
+import { validateStoreVendorExperienceRequest, validateUpdateVendorExperienceRequest } from '../../validators/sales/vendor_experience/VendorExperienceValidators';
8
+import { CustomRequest } from '../../types/token/CustomRequest';
9
+
10
+export const getAllVendorExperience = async (req: Request, res: Response): Promise<Response> => {
11
+    try {
12
+        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
13
+
14
+        const { vendor_experiences, total } = await VendorExperienceService.getAllVendorExperienceService(
15
+            { page, limit, search, sortBy, orderBy },
16
+            req as CustomRequest
17
+        );
18
+
19
+        return VendorExperienceCollection(req, res, vendor_experiences, total, page, limit, 'Vendor experience successfully retrieved');
20
+    } catch (err) {
21
+        return errorResponse(res, err);
22
+    }
23
+};
24
+
25
+export const showVendorExperience = async (req: Request, res: Response) => {
26
+    try {
27
+        const data = await VendorExperienceService.showVendorExperienceService(req as CustomRequest);
28
+        return VendorExperienceResource(res, data, 'Success show vendor experience');
29
+    } catch (err) {
30
+        return errorResponse(res, err);
31
+    }
32
+};
33
+
34
+export const storeVendorExperience = async (req: Request, res: Response): Promise<Response> => {
35
+    try {
36
+        const validatedData = validateStoreVendorExperienceRequest(req.body);
37
+        await VendorExperienceService.storeVendorExperienceService(validatedData, req as CustomRequest);
38
+        return messageSuccessResponse(res, 'Success added vendor experience', 201);
39
+    } catch (err) {
40
+        return errorResponse(res, err);
41
+    }
42
+};
43
+
44
+export const updateVendorExperience = async (req: Request, res: Response): Promise<Response> => {
45
+    try {
46
+        const validatedData = validateUpdateVendorExperienceRequest(req.body);
47
+        await VendorExperienceService.updateVendorExperienceService(validatedData, req as CustomRequest);
48
+        return messageSuccessResponse(res, 'Success update vendor experience');
49
+    } catch (err) {
50
+        return errorResponse(res, err);
51
+    }
52
+};
53
+
54
+export const deleteVendorExperience = async (req: Request, res: Response): Promise<Response> => {
55
+    try {
56
+        await VendorExperienceService.deleteVendorExperienceService(req as CustomRequest);
57
+        return messageSuccessResponse(res, 'Success delete vendor experience');
58
+    } catch (err) {
59
+        return errorResponse(res, err);
60
+    }
61
+};
62
+
63
+// const { VendorExperienceCollection } = require('../../resources/sales/vendor_experience/VendorExperienceCollection.js');
64
+// const { VendorExperienceResource } = require('../../resources/sales/vendor_experience/VendorExperienceResource.js');
65
+// const vendorExperienceService = require('../../services/sales/VendorExperienceService.js');
66
+// const { PaginationParam } = require('../../utils/PaginationParams.js');
67
+// const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
68
+// const { validateStoreVendorHistoryRequest, validateUpdateVendorHistoryRequest } = require('../../validators/sales/vendor_experience/VendorExperienceValidators.js');
69
+
70
+// exports.getAllVendorHistory = async (req, res) => {
71
+//     try {
72
+//         const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
73
+
74
+//         const { vendor_histories, total } = await vendorExperienceService.getAllVendorHistoryService({
75
+//             page, limit, search, sortBy, orderBy
76
+//         }, req);
77
+
78
+//         return VendorExperienceCollection(req, res, vendor_histories, total, page, limit, 'Vendor experience successfully retrieved');
79
+
80
+//     } catch (err) {
81
+//         return errorResponse(res, err);
82
+//     }
83
+// };
84
+
85
+// exports.showVendorHistory = async (req, res) => {
86
+//     try {
87
+//         const data = await vendorExperienceService.showVendorHistoryService(req);
88
+//         return VendorExperienceResource(res, data, 'Success show vendor experience');
89
+//     } catch (err) {
90
+//         return errorResponse(res, err);
91
+//     }
92
+// };
93
+
94
+// exports.storeVendorHistory = async (req, res) => {
95
+//     try {
96
+//         const validatedData = validateStoreVendorHistoryRequest(req.body);
97
+//         await vendorExperienceService.storeVendorHistoryService(validatedData, req);
98
+//         return messageSuccessResponse(res, 'Success added vendor experience', 201);
99
+//     } catch (err) {
100
+//         return errorResponse(res, err);
101
+//     }
102
+// }
103
+
104
+// exports.updateVendorHistory = async (req, res) => {
105
+//     try {
106
+//         const validatedData = validateUpdateVendorHistoryRequest(req.body);
107
+//         await vendorExperienceService.updateVendorHistoryService(validatedData, req);
108
+//         return messageSuccessResponse(res, 'Success update vendor experience');
109
+//     } catch (err) {
110
+//         return errorResponse(res, err);
111
+//     }
112
+// }
113
+
114
+// exports.deleteVendorHistory = async (req, res) => {
115
+//     try {
116
+//         await vendorExperienceService.deleteVendorHistoryService(req);
117
+//         return messageSuccessResponse(res, 'Success delete vendor experience');
118
+//     } catch (err) {
119
+//         return errorResponse(res, err);
120
+//     }
121
+// };

+ 0 - 59
src/controllers/sales/VendorHistoryController.js

@@ -1,59 +0,0 @@
1
-const { VendorHistoriCollection } = require('../../resources/sales/vendor_history/VendorHistoriCollection.js');
2
-const { VendorHistoriResource } = require('../../resources/sales/vendor_history/VendorHistoriResource.js');
3
-const vendorHistoryService = require('../../services/sales/VendorHistoryService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateStoreVendorHistoryRequest, validateUpdateVendorHistoryRequest } = require('../../validators/sales/vendor_history/VendorHistoriValidators.js');
7
-
8
-exports.getAllVendorHistory = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { vendor_histories, total } = await vendorHistoryService.getAllVendorHistoryService({
13
-            page, limit, search, sortBy, orderBy
14
-        }, req);
15
-
16
-        return VendorHistoriCollection(req, res, vendor_histories, total, page, limit, 'Vendor history successfully retrieved');
17
-
18
-    } catch (err) {
19
-        return errorResponse(res, err);
20
-    }
21
-};
22
-
23
-exports.showVendorHistory = async (req, res) => {
24
-    try {
25
-        const data = await vendorHistoryService.showVendorHistoryService(req);
26
-        return VendorHistoriResource(res, data, 'Success show vendor history');
27
-    } catch (err) {
28
-        return errorResponse(res, err);
29
-    }
30
-};
31
-
32
-exports.storeVendorHistory = async (req, res) => {
33
-    try {
34
-        const validatedData = validateStoreVendorHistoryRequest(req.body);
35
-        await vendorHistoryService.storeVendorHistoryService(validatedData, req);
36
-        return messageSuccessResponse(res, 'Success added vendor history', 201);
37
-    } catch (err) {
38
-        return errorResponse(res, err);
39
-    }
40
-}
41
-
42
-exports.updateVendorHistory = async (req, res) => {
43
-    try {
44
-        const validatedData = validateUpdateVendorHistoryRequest(req.body);
45
-        await vendorHistoryService.updateVendorHistoryService(validatedData, req);
46
-        return messageSuccessResponse(res, 'Success update vendor history');
47
-    } catch (err) {
48
-        return errorResponse(res, err);
49
-    }
50
-}
51
-
52
-exports.deleteVendorHistory = async (req, res) => {
53
-    try {
54
-        await vendorHistoryService.deleteVendorHistoryService(req);
55
-        return messageSuccessResponse(res, 'Success delete vendor history');
56
-    } catch (err) {
57
-        return errorResponse(res, err);
58
-    }
59
-};

+ 0 - 61
src/controllers/superadmin/AdminController.js

@@ -1,61 +0,0 @@
1
-const { AdminCollection } = require('../../resources/superadmin/admin/AdminCollection.js');
2
-const { AdminResource } = require('../../resources/superadmin/admin/AdminResource.js');
3
-const adminService = require('../../services/superadmin/AdminService.js');
4
-const { PaginationParam } = require('../../utils/PaginationParams.js');
5
-const { errorResponse, messageSuccessResponse } = require('../../utils/Response.js');
6
-const { validateCreateAdminRequest, validateUpdateAdminRequest } = require('../../validators/superadmin/admin/AdminValidators.js');
7
-
8
-exports.getAllAdmin = async (req, res) => {
9
-    try {
10
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
11
-
12
-        const { admin, total } = await adminService.getAllAdminService({
13
-            page, limit, search, sortBy, orderBy
14
-        });
15
-
16
-        return AdminCollection(req, res, admin, total, page, limit, 'Admin data successfully retrieved');
17
-    } catch (err) {
18
-        return errorResponse(res, err);
19
-    }
20
-};
21
-
22
-exports.showAdmin = async (req, res) => {
23
-    try {
24
-        const id = req.params.id;
25
-        const data = await adminService.showAdminService(id);
26
-        return AdminResource(res, data, 'Success show admin');
27
-    } catch (err) {
28
-        return errorResponse(res, err);
29
-    }
30
-};
31
-
32
-exports.storeAdmin = async (req, res) => {
33
-    try {
34
-        const validated = validateCreateAdminRequest(req.body);
35
-        await adminService.storeAdminService(validated, req);
36
-        return messageSuccessResponse(res, 'Admin user created successfully', 201);
37
-    } catch (err) {
38
-        return errorResponse(res, err);
39
-    }
40
-}
41
-
42
-exports.updateAdmin = async (req, res) => {
43
-    try {
44
-        const id = req.params.id;
45
-        const validatedData = validateUpdateAdminRequest(req.body);
46
-        await adminService.updateAdminService(validatedData, id, req);
47
-        return messageSuccessResponse(res, 'Success update admin');
48
-    } catch (err) {
49
-        return errorResponse(res, err);
50
-    }
51
-}
52
-
53
-exports.deleteAdmin = async (req, res) => {
54
-    try {
55
-        const id = req.params.id;
56
-        await adminService.deleteAdminService(id, req);
57
-        return messageSuccessResponse(res, 'Success delete admin');
58
-    } catch (err) {
59
-        return errorResponse(res, err);
60
-    }
61
-};

+ 0 - 18
src/controllers/superadmin/LogController.js

@@ -1,18 +0,0 @@
1
-const { LogCollection } = require('../../resources/superadmin/log/LogCollection.js');
2
-const logService = require('../../services/superadmin/LogService.js');
3
-const { PaginationParam } = require('../../utils/PaginationParams.js');
4
-const { errorResponse } = require('../../utils/Response.js');
5
-
6
-exports.getAllLogs = async (req, res) => {
7
-    try {
8
-        const { page, limit, search, sortBy, orderBy } = PaginationParam(req);
9
-
10
-        const { logs, total } = await logService.getAllLogsService({
11
-            page, limit, search, sortBy, orderBy
12
-        });
13
-
14
-        return LogCollection(req, res, logs, total, page, limit, 'Logs data successfully retrieved');
15
-    } catch (err) {
16
-        return errorResponse(res, err);
17
-    }
18
-};

+ 34 - 17
src/middleware/CheckRoles.ts

@@ -1,29 +1,18 @@
1 1
 import { Request, Response, NextFunction } from 'express';
2 2
 
3
-interface CustomRequest extends Request {
4
-    tokenData?: {
5
-        realm_access?: {
6
-            roles?: string[];
7
-        };
8
-        [key: string]: any;
9
-    };
10
-}
11
-
12
-const checkRoles = (allowedRoles: string[] = []) => {
13
-    return async (req: CustomRequest, res: Response, next: NextFunction) => {
3
+const checkRoles = (allowedRoles: string[]) => {
4
+    return (req: Request, res: Response, next: NextFunction) => {
14 5
         try {
15
-            const tokenData = req.tokenData;
6
+            const tokenData = (req as any).tokenData;
16 7
             const roles = tokenData?.realm_access?.roles || [];
17 8
 
18 9
             const hasAccess = allowedRoles.some(role => roles.includes(role));
19 10
 
20
-            if (hasAccess) {
21
-                return next();
11
+            if (!hasAccess) {
12
+                return res.status(403).json({ message: 'Access Denied' });
22 13
             }
23 14
 
24
-            const error = new Error('Access Denied') as Error & { statusCode?: number };
25
-            error.statusCode = 403;
26
-            throw error;
15
+            next();
27 16
         } catch (error) {
28 17
             next(error);
29 18
         }
@@ -32,6 +21,34 @@ const checkRoles = (allowedRoles: string[] = []) => {
32 21
 
33 22
 export default checkRoles;
34 23
 
24
+// import { Response, NextFunction } from 'express';
25
+// import { CustomRequest } from '../types/token/CustomRequest';
26
+
27
+// const checkRoles = (allowedRoles: string[] = []) => {
28
+//     return async (req: CustomRequest, res: Response, next: NextFunction) => {
29
+//         try {
30
+//             const tokenData = req.tokenData;
31
+//             const roles = tokenData?.realm_access?.roles || [];
32
+
33
+//             const hasAccess = allowedRoles.some(role => roles.includes(role));
34
+
35
+//             if (hasAccess) {
36
+//                 return next();
37
+//             }
38
+
39
+//             const error = new Error('Access Denied') as Error & { statusCode?: number };
40
+//             error.statusCode = 403;
41
+//             throw error;
42
+//         } catch (error) {
43
+//             next(error);
44
+//         }
45
+//     };
46
+// };
47
+
48
+// export default checkRoles;
49
+
50
+// ========================================================
51
+
35 52
 // module.exports = (allowedRoles = []) => {
36 53
 //     return async (req, res, next) => {
37 54
 //         try {

+ 31 - 9
src/middleware/ExtractToken.ts

@@ -1,11 +1,7 @@
1 1
 import { Request, Response, NextFunction } from 'express';
2
-import jwt from 'jsonwebtoken';
2
+import jwt, { JwtPayload } from 'jsonwebtoken';
3 3
 
4
-interface CustomRequest extends Request {
5
-    tokenData?: any;
6
-}
7
-
8
-const extractToken = async (req: CustomRequest, res: Response, next: NextFunction) => {
4
+export const extractToken = async (req: Request, res: Response, next: NextFunction) => {
9 5
     try {
10 6
         const bearerToken = req.headers.authorization;
11 7
 
@@ -14,16 +10,42 @@ const extractToken = async (req: CustomRequest, res: Response, next: NextFunctio
14 10
         }
15 11
 
16 12
         const token = bearerToken.split(' ')[1];
17
-        const tokenData = jwt.decode(token);
13
+        const tokenData = jwt.decode(token) as JwtPayload;
14
+
15
+        (req as any).tokenData = {
16
+            sub: tokenData?.sub as string,
17
+            realm_access: tokenData?.realm_access
18
+        };
18 19
 
19
-        req.tokenData = tokenData;
20 20
         next();
21 21
     } catch (error) {
22 22
         next(error);
23 23
     }
24 24
 };
25 25
 
26
-export default extractToken;
26
+// import { Response, NextFunction } from 'express';
27
+// import jwt from 'jsonwebtoken';
28
+// import { CustomRequest } from '../types/token/CustomRequest';
29
+
30
+// const extractToken = async (req: CustomRequest, res: Response, next: NextFunction) => {
31
+//     try {
32
+//         const bearerToken = req.headers.authorization;
33
+
34
+//         if (!bearerToken || !bearerToken.startsWith('Bearer ')) {
35
+//             return res.status(401).json({ message: 'Token tidak valid atau tidak ditemukan.' });
36
+//         }
37
+
38
+//         const token = bearerToken.split(' ')[1];
39
+//         const tokenData = jwt.decode(token);
40
+
41
+//         req.tokenData = { sub: tokenData?.sub as string };
42
+//         next();
43
+//     } catch (error) {
44
+//         next(error);
45
+//     }
46
+// };
47
+
48
+// export default extractToken;
27 49
 
28 50
 // module.exports = async (req, res, next) => {
29 51
 //     try {

+ 15 - 2
src/repository/admin/CityRepository.ts

@@ -59,9 +59,22 @@ const CityRepository = {
59 59
         return prisma.city.create({ data });
60 60
     },
61 61
 
62
-    findByNameAndProvince: async (name: string, province_id: string) => {
62
+    // findByNameAndProvince: async (name: string, province_id: string) => {
63
+    //     return prisma.city.findFirst({
64
+    //         where: { name, province_id, deletedAt: null }
65
+    //     });
66
+    // },
67
+
68
+    findByNameAndProvinceId: async (name: string, province_id: string) => {
63 69
         return prisma.city.findFirst({
64
-            where: { name, province_id, deletedAt: null }
70
+            where: {
71
+                name: {
72
+                    equals: name,
73
+                    mode: 'insensitive'
74
+                },
75
+                province_id,
76
+                deletedAt: null,
77
+            }
65 78
         });
66 79
     },
67 80
 

+ 0 - 114
src/repository/admin/ExecutivesHistoryRepository.js

@@ -1,114 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const ExecutivesHistoryRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.executivesHistory.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                hospital: {
13
-                    select: {
14
-                        id: true,
15
-                        name: true,
16
-                        hospital_code: true,
17
-                        type: true,
18
-                        ownership: true,
19
-                        province: {
20
-                            select: {
21
-                                id: true,
22
-                                name: true
23
-                            }
24
-                        },
25
-                        city: {
26
-                            select: {
27
-                                id: true,
28
-                                name: true
29
-                            }
30
-                        },
31
-                        address: true,
32
-                        simrs_type: true,
33
-                        contact: true,
34
-                        image: true,
35
-                        progress_status: true,
36
-                        note: true,
37
-                        created_by: true
38
-                    }
39
-                },
40
-                executive_name: true,
41
-                contact: true,
42
-                status: true,
43
-                start_term: true,
44
-                end_term: true,
45
-                createdAt: true,
46
-                updatedAt: true,
47
-            },
48
-        });
49
-    },
50
-
51
-    countAll: async (where) => {
52
-        return prisma.executivesHistory.count({ where });
53
-    },
54
-
55
-    findById: async (id) => {
56
-        return prisma.executivesHistory.findFirst({
57
-            where: {
58
-                id,
59
-                deletedAt: null
60
-            },
61
-            select: {
62
-                id: true,
63
-                hospital: {
64
-                    select: {
65
-                        id: true,
66
-                        name: true,
67
-                        hospital_code: true,
68
-                        type: true,
69
-                        ownership: true,
70
-                        province: {
71
-                            select: {
72
-                                id: true,
73
-                                name: true
74
-                            }
75
-                        },
76
-                        city: {
77
-                            select: {
78
-                                id: true,
79
-                                name: true
80
-                            }
81
-                        },
82
-                        address: true,
83
-                        simrs_type: true,
84
-                        contact: true,
85
-                        image: true,
86
-                        progress_status: true,
87
-                        note: true,
88
-                        created_by: true
89
-                    }
90
-                },
91
-                executive_name: true,
92
-                contact: true,
93
-                status: true,
94
-                start_term: true,
95
-                end_term: true,
96
-                createdAt: true,
97
-                updatedAt: true,
98
-            },
99
-        });
100
-    },
101
-
102
-    create: async (data) => {
103
-        return prisma.executivesHistory.create({ data });
104
-    },
105
-
106
-    update: async (id, data) => {
107
-        return prisma.executivesHistory.update({
108
-            where: { id },
109
-            data
110
-        });
111
-    },
112
-};
113
-
114
-module.exports = ExecutivesHistoryRepository;

+ 184 - 0
src/repository/admin/ExecutivesHistoryRepository.ts

@@ -0,0 +1,184 @@
1
+import { PrismaClient, Prisma } from '@prisma/client';
2
+
3
+const prisma = new PrismaClient();
4
+
5
+export const ExecutivesHistoryRepository = {
6
+    findAll: async ({
7
+        skip,
8
+        take,
9
+        where,
10
+        orderBy
11
+    }: {
12
+        skip?: number;
13
+        take?: number;
14
+        where?: Prisma.ExecutivesHistoryWhereInput;
15
+        orderBy?: Prisma.ExecutivesHistoryOrderByWithRelationInput;
16
+    }) => {
17
+        return prisma.executivesHistory.findMany({
18
+            where,
19
+            skip,
20
+            take,
21
+            orderBy,
22
+            select: {
23
+                id: true,
24
+                executive_name: true,
25
+                contact: true,
26
+                status: true,
27
+                start_term: true,
28
+                end_term: true,
29
+                createdAt: true,
30
+                updatedAt: true,
31
+            },
32
+        });
33
+    },
34
+
35
+    countAll: async (where?: Prisma.ExecutivesHistoryWhereInput) => {
36
+        return prisma.executivesHistory.count({ where });
37
+    },
38
+
39
+    findById: async (id: string) => {
40
+        return prisma.executivesHistory.findFirst({
41
+            where: {
42
+                id,
43
+                deletedAt: null,
44
+            },
45
+            select: {
46
+                id: true,
47
+                executive_name: true,
48
+                contact: true,
49
+                status: true,
50
+                start_term: true,
51
+                end_term: true,
52
+                createdAt: true,
53
+                updatedAt: true,
54
+            },
55
+        });
56
+    },
57
+
58
+    create: async (data: Prisma.ExecutivesHistoryCreateInput) => {
59
+        return prisma.executivesHistory.create({ data });
60
+    },
61
+
62
+    update: async (id: string, data: Prisma.ExecutivesHistoryUpdateInput) => {
63
+        return prisma.executivesHistory.update({
64
+            where: { id },
65
+            data,
66
+        });
67
+    },
68
+};
69
+
70
+
71
+// const prisma = require('../../prisma/PrismaClient.js');
72
+
73
+// const ExecutivesHistoryRepository = {
74
+//     findAll: async ({ skip, take, where, orderBy }) => {
75
+//         return prisma.executivesHistory.findMany({
76
+//             where,
77
+//             skip,
78
+//             take,
79
+//             orderBy,
80
+//             select: {
81
+//                 id: true,
82
+//                 hospital: {
83
+//                     select: {
84
+//                         id: true,
85
+//                         name: true,
86
+//                         hospital_code: true,
87
+//                         type: true,
88
+//                         ownership: true,
89
+//                         province: {
90
+//                             select: {
91
+//                                 id: true,
92
+//                                 name: true
93
+//                             }
94
+//                         },
95
+//                         city: {
96
+//                             select: {
97
+//                                 id: true,
98
+//                                 name: true
99
+//                             }
100
+//                         },
101
+//                         address: true,
102
+//                         // simrs_type: true,
103
+//                         contact: true,
104
+//                         image: true,
105
+//                         progress_status: true,
106
+//                         note: true,
107
+//                         created_by: true
108
+//                     }
109
+//                 },
110
+//                 executive_name: true,
111
+//                 contact: true,
112
+//                 status: true,
113
+//                 start_term: true,
114
+//                 end_term: true,
115
+//                 createdAt: true,
116
+//                 updatedAt: true,
117
+//             },
118
+//         });
119
+//     },
120
+
121
+//     countAll: async (where) => {
122
+//         return prisma.executivesHistory.count({ where });
123
+//     },
124
+
125
+//     findById: async (id) => {
126
+//         return prisma.executivesHistory.findFirst({
127
+//             where: {
128
+//                 id,
129
+//                 deletedAt: null
130
+//             },
131
+//             select: {
132
+//                 id: true,
133
+//                 hospital: {
134
+//                     select: {
135
+//                         id: true,
136
+//                         name: true,
137
+//                         hospital_code: true,
138
+//                         type: true,
139
+//                         ownership: true,
140
+//                         province: {
141
+//                             select: {
142
+//                                 id: true,
143
+//                                 name: true
144
+//                             }
145
+//                         },
146
+//                         city: {
147
+//                             select: {
148
+//                                 id: true,
149
+//                                 name: true
150
+//                             }
151
+//                         },
152
+//                         address: true,
153
+//                         // simrs_type: true,
154
+//                         contact: true,
155
+//                         image: true,
156
+//                         progress_status: true,
157
+//                         note: true,
158
+//                         created_by: true
159
+//                     }
160
+//                 },
161
+//                 executive_name: true,
162
+//                 contact: true,
163
+//                 status: true,
164
+//                 start_term: true,
165
+//                 end_term: true,
166
+//                 createdAt: true,
167
+//                 updatedAt: true,
168
+//             },
169
+//         });
170
+//     },
171
+
172
+//     create: async (data) => {
173
+//         return prisma.executivesHistory.create({ data });
174
+//     },
175
+
176
+//     update: async (id, data) => {
177
+//         return prisma.executivesHistory.update({
178
+//             where: { id },
179
+//             data
180
+//         });
181
+//     },
182
+// };
183
+
184
+// module.exports = ExecutivesHistoryRepository;

+ 0 - 153
src/repository/admin/HospitalRepository.js

@@ -1,153 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const HospitalRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        const hospitalsRaw = await prisma.hospital.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                name: true,
13
-                hospital_code: true,
14
-                type: true,
15
-                ownership: true,
16
-                province: { select: { id: true, name: true } },
17
-                city: { select: { id: true, name: true } },
18
-                address: true,
19
-                // simrs_type: true,
20
-                contact: true,
21
-                image: true,
22
-                progress_status: true,
23
-                note: true,
24
-                latitude: true,
25
-                longitude: true,
26
-                gmaps_url: true,
27
-                created_by: true,
28
-                createdAt: true,
29
-                updatedAt: true,
30
-                vendor_experiences: {
31
-                    where: {
32
-                        status: "active",
33
-                        deletedAt: null
34
-                    },
35
-                    select: {
36
-                        vendor: {
37
-                            select: {
38
-                                id: true,
39
-                                name: true,
40
-                                name_pt: true,
41
-                                strengths: true,
42
-                                weaknesses: true,
43
-                                website: true,
44
-                            }
45
-                        }
46
-                    }
47
-                }
48
-            }
49
-        });
50
-
51
-        return hospitalsRaw.map(hospital => {
52
-            const { vendor_histories, ...rest } = hospital;
53
-            return {
54
-                ...rest,
55
-                vendor: vendor_histories?.[0]?.vendor || null
56
-            };
57
-        });
58
-    },
59
-
60
-    countAll: async (where) => {
61
-        return prisma.hospital.count({ where });
62
-    },
63
-
64
-    findById: async (id) => {
65
-        const hospitalRaw = await prisma.hospital.findFirst({
66
-            where: {
67
-                id,
68
-                deletedAt: null
69
-            },
70
-            select: {
71
-                id: true,
72
-                name: true,
73
-                hospital_code: true,
74
-                type: true,
75
-                ownership: true,
76
-                province: { select: { id: true, name: true } },
77
-                city: { select: { id: true, name: true } },
78
-                address: true,
79
-                // simrs_type: true,
80
-                contact: true,
81
-                image: true,
82
-                progress_status: true,
83
-                note: true,
84
-                latitude: true,
85
-                longitude: true,
86
-                gmaps_url: true,
87
-                created_by: true,
88
-                createdAt: true,
89
-                updatedAt: true,
90
-                vendor_experiences: {
91
-                    where: {
92
-                        status: "active",
93
-                        deletedAt: null
94
-                    },
95
-                    take: 1,
96
-                    select: {
97
-                        vendor: {
98
-                            select: {
99
-                                id: true,
100
-                                name: true,
101
-                                name_pt: true,
102
-                                strengths: true,
103
-                                weaknesses: true,
104
-                                website: true,
105
-                            }
106
-                        }
107
-                    }
108
-                }
109
-            }
110
-        });
111
-
112
-        if (!hospitalRaw) return null;
113
-
114
-        const { vendor_histories, ...rest } = hospitalRaw;
115
-        return {
116
-            ...rest,
117
-            vendor: vendor_histories?.[0]?.vendor || null
118
-        };
119
-    },
120
-
121
-    create: async (data) => {
122
-        return prisma.hospital.create({ data });
123
-    },
124
-
125
-    // update: async (id, data) => {
126
-    //     return prisma.hospital.update({
127
-    //         where: { id },
128
-    //         data: {
129
-    //             name: data.name,
130
-    //             hospital_code: data.hospital_code,
131
-    //             type: data.type,
132
-    //             ownership: data.ownership,
133
-    //             province: { connect: { id: data.province_id } },
134
-    //             city: { connect: { id: data.city_id } },
135
-    //             address: data.address,
136
-    //             // simrs_type: data.simrs_type,
137
-    //             contact: data.contact,
138
-    //             note: data.note,
139
-    //             image: data.image,
140
-    //             progress_status: data.progress_status,
141
-    //         }
142
-    //     });
143
-    // },
144
-
145
-    update: async (id, data) => {
146
-        return prisma.hospital.update({
147
-            where: { id },
148
-            data
149
-        });
150
-    },
151
-};
152
-
153
-module.exports = HospitalRepository;

+ 300 - 0
src/repository/admin/HospitalRepository.ts

@@ -0,0 +1,300 @@
1
+import prisma from '../../prisma/PrismaClient';
2
+import { Prisma } from '@prisma/client';
3
+
4
+interface FindAllParams {
5
+    skip: number;
6
+    take: number;
7
+    where?: Prisma.HospitalWhereInput;
8
+    orderBy?: Prisma.HospitalOrderByWithRelationInput;
9
+}
10
+
11
+const HospitalRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllParams) => {
13
+        const hospitalsRaw = await prisma.hospital.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                name: true,
21
+                hospital_code: true,
22
+                type: true,
23
+                ownership: true,
24
+                province: { select: { id: true, name: true } },
25
+                city: { select: { id: true, name: true } },
26
+                address: true,
27
+                // simrs_type: true,
28
+                contact: true,
29
+                image: true,
30
+                progress_status: true,
31
+                note: true,
32
+                latitude: true,
33
+                longitude: true,
34
+                gmaps_url: true,
35
+                created_by: true,
36
+                createdAt: true,
37
+                updatedAt: true,
38
+                user: { select: { id: true, fullname: true } },
39
+                vendor_experiences: {
40
+                    where: {
41
+                        status: 'active',
42
+                        deletedAt: null,
43
+                    },
44
+                    select: {
45
+                        vendor: {
46
+                            select: {
47
+                                id: true,
48
+                                name: true,
49
+                                name_pt: true,
50
+                                strengths: true,
51
+                                weaknesses: true,
52
+                                website: true,
53
+                            },
54
+                        },
55
+                    },
56
+                },
57
+            },
58
+        });
59
+
60
+        return hospitalsRaw.map((hospital) => {
61
+            const { vendor_experiences, ...rest } = hospital;
62
+            return {
63
+                ...rest,
64
+                vendor: vendor_experiences?.[0]?.vendor || null,
65
+            };
66
+        });
67
+    },
68
+
69
+    countAll: async (where: Prisma.HospitalWhereInput) => {
70
+        return prisma.hospital.count({ where });
71
+    },
72
+
73
+    findById: async (id: string) => {
74
+        const hospitalRaw = await prisma.hospital.findFirst({
75
+            where: {
76
+                id,
77
+                deletedAt: null,
78
+            },
79
+            select: {
80
+                id: true,
81
+                name: true,
82
+                hospital_code: true,
83
+                type: true,
84
+                ownership: true,
85
+                province: { select: { id: true, name: true } },
86
+                city: { select: { id: true, name: true } },
87
+                address: true,
88
+                // simrs_type: true,
89
+                contact: true,
90
+                image: true,
91
+                progress_status: true,
92
+                note: true,
93
+                latitude: true,
94
+                longitude: true,
95
+                gmaps_url: true,
96
+                created_by: true,
97
+                createdAt: true,
98
+                updatedAt: true,
99
+                user: { select: { id: true, fullname: true } },
100
+                vendor_experiences: {
101
+                    where: {
102
+                        status: 'active',
103
+                        deletedAt: null,
104
+                    },
105
+                    take: 1,
106
+                    select: {
107
+                        vendor: {
108
+                            select: {
109
+                                id: true,
110
+                                name: true,
111
+                                name_pt: true,
112
+                                strengths: true,
113
+                                weaknesses: true,
114
+                                website: true,
115
+                            },
116
+                        },
117
+                    },
118
+                },
119
+            },
120
+        });
121
+
122
+        if (!hospitalRaw) return null;
123
+
124
+        const { vendor_experiences, ...rest } = hospitalRaw;
125
+        return {
126
+            ...rest,
127
+            vendor: vendor_experiences?.[0]?.vendor || null,
128
+        };
129
+    },
130
+
131
+    create: async (data: Prisma.HospitalCreateInput) => {
132
+        return prisma.hospital.create({ data });
133
+    },
134
+
135
+    update: async (id: string, data: Prisma.HospitalUpdateInput) => {
136
+        return prisma.hospital.update({
137
+            where: { id },
138
+            data,
139
+        });
140
+    },
141
+};
142
+
143
+export default HospitalRepository;
144
+
145
+
146
+// const prisma = require('../../prisma/PrismaClient.js');
147
+
148
+// const HospitalRepository = {
149
+//     findAll: async ({ skip, take, where, orderBy }) => {
150
+//         const hospitalsRaw = await prisma.hospital.findMany({
151
+//             where,
152
+//             skip,
153
+//             take,
154
+//             orderBy,
155
+//             select: {
156
+//                 id: true,
157
+//                 name: true,
158
+//                 hospital_code: true,
159
+//                 type: true,
160
+//                 ownership: true,
161
+//                 province: { select: { id: true, name: true } },
162
+//                 city: { select: { id: true, name: true } },
163
+//                 address: true,
164
+//                 // simrs_type: true,
165
+//                 contact: true,
166
+//                 image: true,
167
+//                 progress_status: true,
168
+//                 note: true,
169
+//                 latitude: true,
170
+//                 longitude: true,
171
+//                 gmaps_url: true,
172
+//                 created_by: true,
173
+//                 createdAt: true,
174
+//                 updatedAt: true,
175
+//                 user: { select: { id: true, fullname: true } },
176
+//                 vendor_experiences: {
177
+//                     where: {
178
+//                         status: "active",
179
+//                         deletedAt: null
180
+//                     },
181
+//                     select: {
182
+//                         vendor: {
183
+//                             select: {
184
+//                                 id: true,
185
+//                                 name: true,
186
+//                                 name_pt: true,
187
+//                                 strengths: true,
188
+//                                 weaknesses: true,
189
+//                                 website: true,
190
+//                             }
191
+//                         }
192
+//                     }
193
+//                 }
194
+//             }
195
+//         });
196
+
197
+//         return hospitalsRaw.map(hospital => {
198
+//             const { vendor_experiences, ...rest } = hospital;
199
+//             return {
200
+//                 ...rest,
201
+//                 vendor: vendor_experiences?.[0]?.vendor || null
202
+//             };
203
+//         });
204
+//     },
205
+
206
+//     countAll: async (where) => {
207
+//         return prisma.hospital.count({ where });
208
+//     },
209
+
210
+//     findById: async (id) => {
211
+//         const hospitalRaw = await prisma.hospital.findFirst({
212
+//             where: {
213
+//                 id,
214
+//                 deletedAt: null
215
+//             },
216
+//             select: {
217
+//                 id: true,
218
+//                 name: true,
219
+//                 hospital_code: true,
220
+//                 type: true,
221
+//                 ownership: true,
222
+//                 province: { select: { id: true, name: true } },
223
+//                 city: { select: { id: true, name: true } },
224
+//                 address: true,
225
+//                 // simrs_type: true,
226
+//                 contact: true,
227
+//                 image: true,
228
+//                 progress_status: true,
229
+//                 note: true,
230
+//                 latitude: true,
231
+//                 longitude: true,
232
+//                 gmaps_url: true,
233
+//                 created_by: true,
234
+//                 createdAt: true,
235
+//                 updatedAt: true,
236
+//                 user: { select: { id: true, fullname: true } },
237
+//                 vendor_experiences: {
238
+//                     where: {
239
+//                         status: "active",
240
+//                         deletedAt: null
241
+//                     },
242
+//                     take: 1,
243
+//                     select: {
244
+//                         vendor: {
245
+//                             select: {
246
+//                                 id: true,
247
+//                                 name: true,
248
+//                                 name_pt: true,
249
+//                                 strengths: true,
250
+//                                 weaknesses: true,
251
+//                                 website: true,
252
+//                             }
253
+//                         }
254
+//                     }
255
+//                 }
256
+//             }
257
+//         });
258
+
259
+//         if (!hospitalRaw) return null;
260
+
261
+//         const { vendor_experiences, ...rest } = hospitalRaw;
262
+//         return {
263
+//             ...rest,
264
+//             vendor: vendor_experiences?.[0]?.vendor || null
265
+//         };
266
+//     },
267
+
268
+//     create: async (data) => {
269
+//         return prisma.hospital.create({ data });
270
+//     },
271
+
272
+//     // update: async (id, data) => {
273
+//     //     return prisma.hospital.update({
274
+//     //         where: { id },
275
+//     //         data: {
276
+//     //             name: data.name,
277
+//     //             hospital_code: data.hospital_code,
278
+//     //             type: data.type,
279
+//     //             ownership: data.ownership,
280
+//     //             province: { connect: { id: data.province_id } },
281
+//     //             city: { connect: { id: data.city_id } },
282
+//     //             address: data.address,
283
+//     //             // simrs_type: data.simrs_type,
284
+//     //             contact: data.contact,
285
+//     //             note: data.note,
286
+//     //             image: data.image,
287
+//     //             progress_status: data.progress_status,
288
+//     //         }
289
+//     //     });
290
+//     // },
291
+
292
+//     update: async (id, data) => {
293
+//         return prisma.hospital.update({
294
+//             where: { id },
295
+//             data
296
+//         });
297
+//     },
298
+// };
299
+
300
+// module.exports = HospitalRepository;

+ 12 - 0
src/repository/admin/ProvinceRepository.ts

@@ -43,6 +43,18 @@ const ProvinceRepository = {
43 43
         });
44 44
     },
45 45
 
46
+    findByName: async (name: string) => {
47
+        return prisma.province.findFirst({
48
+            where: {
49
+                name: {
50
+                    equals: name,
51
+                    mode: "insensitive",
52
+                },
53
+                deletedAt: null,
54
+            },
55
+        });
56
+    },
57
+
46 58
     create: async (data: Prisma.ProvinceCreateInput) => {
47 59
         return prisma.province.create({ data });
48 60
     },

+ 0 - 261
src/repository/admin/SalesRepository.js

@@ -1,261 +0,0 @@
1
-const axios = require('axios');
2
-const qs = require('qs');
3
-const {
4
-    KEYCLOAK_REALM,
5
-    KEYCLOAK_ADMIN_URL,
6
-    CLIENT_ID,
7
-    CLIENT_SECRET
8
-} = require('../../../config/keycloak.js');
9
-const HttpException = require('../../utils/HttpException.js');
10
-const bcrypt = require('bcrypt');
11
-const prisma = require('../../prisma/PrismaClient.js');
12
-
13
-const getAdminToken = async () => {
14
-    const tokenParams = qs.stringify({
15
-        grant_type: 'client_credentials',
16
-        client_id: CLIENT_ID,
17
-        client_secret: CLIENT_SECRET
18
-    });
19
-
20
-    const { data } = await axios.post(
21
-        `${KEYCLOAK_ADMIN_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`,
22
-        tokenParams,
23
-        {
24
-            headers: {
25
-                'Content-Type': 'application/x-www-form-urlencoded'
26
-            }
27
-        }
28
-    );
29
-
30
-    return data.access_token;
31
-};
32
-
33
-const KeycloakRepository = {
34
-    createUser: async (userData) => {
35
-        const token = await getAdminToken();
36
-
37
-        // Cek apakah username sudah terpakai
38
-        const { data: usersByUsername } = await axios.get(
39
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?username=${encodeURIComponent(userData.username)}`,
40
-            { headers: { Authorization: `Bearer ${token}` } }
41
-        );
42
-
43
-        if (usersByUsername.length > 0) {
44
-            throw new HttpException('Username already exists in Keycloak', 409);
45
-        }
46
-
47
-        // Cek apakah email sudah terpakai
48
-        const { data: usersByEmail } = await axios.get(
49
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?email=${encodeURIComponent(userData.email)}`,
50
-            { headers: { Authorization: `Bearer ${token}` } }
51
-        );
52
-
53
-        if (usersByEmail.length > 0) {
54
-            throw new HttpException('Email already exists in Keycloak', 409);
55
-        }
56
-
57
-        const response = await axios.post(
58
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`,
59
-            {
60
-                username: userData.username,
61
-                email: userData.email,
62
-                firstName: userData.firstname,
63
-                lastName: userData.lastname,
64
-                enabled: true,
65
-                credentials: [{
66
-                    type: "password",
67
-                    value: userData.password,
68
-                    temporary: false
69
-                }]
70
-            },
71
-            { headers: { Authorization: `Bearer ${token}` } }
72
-        );
73
-
74
-        return response.headers.location.split('/').pop();
75
-    },
76
-
77
-    assignSalesRole: async (userId) => {
78
-        const token = await getAdminToken();
79
-
80
-        // Get role sales
81
-        const { data: roles } = await axios.get(
82
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/roles`,
83
-            { headers: { Authorization: `Bearer ${token}` } }
84
-        );
85
-
86
-        const salesRole = roles.find(role => role.name === 'sales');
87
-        if (!salesRole) throw new HttpException('Sales role not found in Keycloak', 500);
88
-
89
-        // Assign role to user
90
-        await axios.post(
91
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}/role-mappings/realm`,
92
-            [salesRole],
93
-            { headers: { Authorization: `Bearer ${token}` } }
94
-        );
95
-    },
96
-
97
-    updateUser: async (userId, updatedData) => {
98
-        const token = await getAdminToken();
99
-
100
-        await axios.put(
101
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
102
-            {
103
-                firstName: updatedData.firstname,
104
-                lastName: updatedData.lastname,
105
-                email: updatedData.email,
106
-                credentials: updatedData.password ? [{
107
-                    type: 'password',
108
-                    value: updatedData.password,
109
-                    temporary: false
110
-                }] : undefined
111
-            },
112
-            { headers: { Authorization: `Bearer ${token}` } }
113
-        );
114
-    },
115
-
116
-    deleteUser: async (userId) => {
117
-        const token = await getAdminToken();
118
-
119
-        await axios.delete(
120
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
121
-            { headers: { Authorization: `Bearer ${token}` } }
122
-        );
123
-    }
124
-};
125
-
126
-const UserRepository = {
127
-    createUser: async (userId, userData) => {
128
-        const hashedPassword = await bcrypt.hash(userData.password, 10);
129
-
130
-        return prisma.user.create({
131
-            data: {
132
-                id: userId,
133
-                username: userData.username,
134
-                email: userData.email,
135
-                firstname: userData.firstname,
136
-                lastname: userData.lastname,
137
-                password: hashedPassword,
138
-                role: 'sales'
139
-            }
140
-        });
141
-    },
142
-
143
-    findAll: async ({ skip, take, where, orderBy }) => {
144
-        return prisma.user.findMany({
145
-            where: {
146
-                ...where,
147
-                role: 'sales'
148
-            },
149
-            skip,
150
-            take,
151
-            orderBy,
152
-            select: {
153
-                id: true,
154
-                username: true,
155
-                email: true,
156
-                firstname: true,
157
-                lastname: true,
158
-                role: true,
159
-                user_areas: {
160
-                    select: {
161
-                        id: true,
162
-                        province: {
163
-                            select: {
164
-                                id: true,
165
-                                name: true
166
-                            }
167
-                        }
168
-                    }
169
-                },
170
-                createdAt: true,
171
-                updatedAt: true,
172
-            },
173
-        });
174
-    },
175
-
176
-    countAll: async (where) => {
177
-        return prisma.user.count({
178
-            where: {
179
-                ...where,
180
-                role: 'admin'
181
-            },
182
-        });
183
-    },
184
-
185
-    findById: async (id) => {
186
-        return prisma.user.findFirst({
187
-            where: {
188
-                id,
189
-                deletedAt: null
190
-            },
191
-            select: {
192
-                id: true,
193
-                username: true,
194
-                email: true,
195
-                firstname: true,
196
-                lastname: true,
197
-                user_areas: {
198
-                    select: {
199
-                        id: true,
200
-                        province: {
201
-                            select: {
202
-                                id: true,
203
-                                name: true
204
-                            }
205
-                        }
206
-                    }
207
-                },
208
-                createdAt: true,
209
-                updatedAt: true,
210
-            }
211
-        });
212
-    },
213
-
214
-    updateUser: async (id, updatedData) => {
215
-        const updatePayload = {
216
-            email: updatedData.email,
217
-            firstname: updatedData.firstname,
218
-            lastname: updatedData.lastname
219
-        };
220
-
221
-        if (updatedData.password) {
222
-            updatePayload.password = await bcrypt.hash(updatedData.password, 10);
223
-        }
224
-
225
-        return prisma.user.update({
226
-            where: { id },
227
-            data: updatePayload
228
-        });
229
-    },
230
-
231
-    deleteUser: async (id) => {
232
-        return prisma.user.update({
233
-            where: { id },
234
-            data: {
235
-                deletedAt: new Date()
236
-            }
237
-        });
238
-    }
239
-};
240
-
241
-const UserAreaRepository = {
242
-    createMany: async (userId, provinceIds) => {
243
-        const data = provinceIds.map(provinceId => ({
244
-            user_id: userId,
245
-            province_id: provinceId
246
-        }));
247
-
248
-        return prisma.userArea.createMany({
249
-            data,
250
-            skipDuplicates: true
251
-        });
252
-    },
253
-
254
-    deleteByUserId: async (userId) => {
255
-        return prisma.userArea.deleteMany({
256
-            where: { user_id: userId }
257
-        });
258
-    }
259
-};
260
-
261
-module.exports = { KeycloakRepository, UserRepository, UserAreaRepository };

+ 0 - 64
src/repository/admin/StatusHistoryRepository.js

@@ -1,64 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const StatusHistoryRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.statusHistory.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                hospital: {
13
-                    select: {
14
-                        id: true,
15
-                        name: true,
16
-                        // hospital_code: true,
17
-                        // type: true,
18
-                        // ownership: true,
19
-                        // province: {
20
-                        //     select: {
21
-                        //         id: true,
22
-                        //         name: true
23
-                        //     }
24
-                        // },
25
-                        // city: {
26
-                        //     select: {
27
-                        //         id: true,
28
-                        //         name: true
29
-                        //     }
30
-                        // },
31
-                        // address: true,
32
-                        // simrs_type: true,
33
-                        // contact: true,
34
-                        // image: true,
35
-                        progress_status: true,
36
-                        // note: true,
37
-                        // user: {
38
-                        //     select: {
39
-                        //         id: true,
40
-                        //         username: true
41
-                        //     }
42
-                        // }
43
-                    }
44
-                },
45
-                user_id: true,
46
-                old_status: true,
47
-                new_status: true,
48
-                note: true,
49
-                createdAt: true,
50
-                updatedAt: true,
51
-            },
52
-        });
53
-    },
54
-
55
-    countAll: async (where) => {
56
-        return prisma.statusHistory.count({ where });
57
-    },
58
-
59
-    create: async (data) => {
60
-        return prisma.statusHistory.create({ data });
61
-    },
62
-};
63
-
64
-module.exports = StatusHistoryRepository;

+ 89 - 0
src/repository/admin/StatusHistoryRepository.ts

@@ -0,0 +1,89 @@
1
+import { Prisma } from '@prisma/client';
2
+import prisma from '../../prisma/PrismaClient';
3
+
4
+type FindAllArgs = {
5
+    skip: number;
6
+    take: number;
7
+    where: Prisma.StatusHistoryWhereInput;
8
+    orderBy: Prisma.StatusHistoryOrderByWithRelationInput;
9
+};
10
+
11
+const StatusHistoryRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllArgs) => {
13
+        return prisma.statusHistory.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                user: {
21
+                    select: {
22
+                        id: true,
23
+                        fullname: true,
24
+                    },
25
+                },
26
+                old_status: true,
27
+                new_status: true,
28
+                note: true,
29
+                createdAt: true,
30
+                updatedAt: true,
31
+            },
32
+        });
33
+    },
34
+
35
+    countAll: async (where: Prisma.StatusHistoryWhereInput) => {
36
+        return prisma.statusHistory.count({ where });
37
+    },
38
+
39
+    create: async (data: Prisma.StatusHistoryCreateInput) => {
40
+        return prisma.statusHistory.create({ data });
41
+    },
42
+};
43
+
44
+export default StatusHistoryRepository;
45
+
46
+
47
+// const prisma = require('../../prisma/PrismaClient.js');
48
+
49
+// const StatusHistoryRepository = {
50
+//     findAll: async ({ skip, take, where, orderBy }) => {
51
+//         return prisma.statusHistory.findMany({
52
+//             where,
53
+//             skip,
54
+//             take,
55
+//             orderBy,
56
+//             select: {
57
+//                 id: true,
58
+//                 hospital: {
59
+//                     select: {
60
+//                         id: true,
61
+//                         name: true,
62
+//                         progress_status: true,
63
+//                     }
64
+//                 },
65
+//                 user: {
66
+//                     select: {
67
+//                         id: true,
68
+//                         fullname: true
69
+//                     }
70
+//                 },
71
+//                 old_status: true,
72
+//                 new_status: true,
73
+//                 note: true,
74
+//                 createdAt: true,
75
+//                 updatedAt: true,
76
+//             },
77
+//         });
78
+//     },
79
+
80
+//     countAll: async (where) => {
81
+//         return prisma.statusHistory.count({ where });
82
+//     },
83
+
84
+//     create: async (data) => {
85
+//         return prisma.statusHistory.create({ data });
86
+//     },
87
+// };
88
+
89
+// module.exports = StatusHistoryRepository;

+ 0 - 142
src/repository/admin/VendorExperienceRepository.js

@@ -1,142 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const VendorExperienceRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.vendorExperience.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                // hospital: {
13
-                //     select: {
14
-                //         id: true,
15
-                //         name: true,
16
-                //         hospital_code: true,
17
-                //         type: true,
18
-                //         ownership: true,
19
-                //         province: {
20
-                //             select: {
21
-                //                 id: true,
22
-                //                 name: true
23
-                //             }
24
-                //         },
25
-                //         city: {
26
-                //             select: {
27
-                //                 id: true,
28
-                //                 name: true
29
-                //             }
30
-                //         },
31
-                //         address: true,
32
-                //         simrs_type: true,
33
-                //         contact: true,
34
-                //         image: true,
35
-                //         progress_status: true,
36
-                //         note: true,
37
-                //         created_by: true
38
-                //     }
39
-                // },
40
-                vendor: {
41
-                    select: {
42
-                        id: true,
43
-                        name: true,
44
-                        name_pt: true,
45
-                        strengths: true,
46
-                        weaknesses: true,
47
-                        website: true,
48
-                        created_by: true,
49
-                    }
50
-                },
51
-                status: true,
52
-                simrs_type: true,
53
-                contract_value_min: true,
54
-                contract_value_max: true,
55
-                contract_start_date: true,
56
-                contract_expired_date: true,
57
-                positive_notes: true,
58
-                negative_notes: true,
59
-                createdAt: true,
60
-                updatedAt: true,
61
-            },
62
-        });
63
-    },
64
-
65
-    countAll: async (where) => {
66
-        return prisma.vendorExperience.count({ where });
67
-    },
68
-
69
-    findById: async (id) => {
70
-        return prisma.vendorExperience.findFirst({
71
-            where: {
72
-                id,
73
-                deletedAt: null
74
-            },
75
-            select: {
76
-                id: true,
77
-                // hospital: {
78
-                //     select: {
79
-                //         id: true,
80
-                //         name: true,
81
-                //         hospital_code: true,
82
-                //         type: true,
83
-                //         ownership: true,
84
-                //         province: {
85
-                //             select: {
86
-                //                 id: true,
87
-                //                 name: true
88
-                //             }
89
-                //         },
90
-                //         city: {
91
-                //             select: {
92
-                //                 id: true,
93
-                //                 name: true
94
-                //             }
95
-                //         },
96
-                //         address: true,
97
-                //         simrs_type: true,
98
-                //         contact: true,
99
-                //         image: true,
100
-                //         progress_status: true,
101
-                //         note: true,
102
-                //         created_by: true
103
-                //     }
104
-                // },
105
-                vendor: {
106
-                    select: {
107
-                        id: true,
108
-                        name: true,
109
-                        name_pt: true,
110
-                        strengths: true,
111
-                        weaknesses: true,
112
-                        website: true,
113
-                        created_by: true,
114
-                    }
115
-                },
116
-                status: true,
117
-                simrs_type: true,
118
-                contract_value_min: true,
119
-                contract_value_max: true,
120
-                contract_start_date: true,
121
-                contract_expired_date: true,
122
-                positive_notes: true,
123
-                negative_notes: true,
124
-                createdAt: true,
125
-                updatedAt: true,
126
-            },
127
-        });
128
-    },
129
-
130
-    create: async (data) => {
131
-        return prisma.vendorExperience.create({ data });
132
-    },
133
-
134
-    update: async (id, data) => {
135
-        return prisma.vendorExperience.update({
136
-            where: { id },
137
-            data
138
-        });
139
-    },
140
-};
141
-
142
-module.exports = VendorExperienceRepository;

+ 238 - 0
src/repository/admin/VendorExperienceRepository.ts

@@ -0,0 +1,238 @@
1
+import { PrismaClient, Prisma } from '@prisma/client';
2
+const prisma = new PrismaClient();
3
+
4
+interface FindAllParams {
5
+    skip?: number;
6
+    take?: number;
7
+    where?: Prisma.VendorExperienceWhereInput;
8
+    orderBy?: Prisma.VendorExperienceOrderByWithRelationInput;
9
+}
10
+
11
+const VendorExperienceRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllParams) => {
13
+        return prisma.vendorExperience.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                vendor: {
21
+                    select: {
22
+                        id: true,
23
+                        name: true,
24
+                        name_pt: true,
25
+                        strengths: true,
26
+                        weaknesses: true,
27
+                        website: true,
28
+                        created_by: true,
29
+                    },
30
+                },
31
+                status: true,
32
+                simrs_type: true,
33
+                contract_value_min: true,
34
+                contract_value_max: true,
35
+                contract_start_date: true,
36
+                contract_expired_date: true,
37
+                positive_notes: true,
38
+                negative_notes: true,
39
+                createdAt: true,
40
+                updatedAt: true,
41
+            },
42
+        });
43
+    },
44
+
45
+    countAll: async (where?: Prisma.VendorExperienceWhereInput) => {
46
+        return prisma.vendorExperience.count({ where });
47
+    },
48
+
49
+    findById: async (id: string) => {
50
+        return prisma.vendorExperience.findFirst({
51
+            where: {
52
+                id,
53
+                deletedAt: null,
54
+            },
55
+            select: {
56
+                id: true,
57
+                vendor_id: true,
58
+                vendor: {
59
+                    select: {
60
+                        id: true,
61
+                        name: true,
62
+                        name_pt: true,
63
+                        strengths: true,
64
+                        weaknesses: true,
65
+                        website: true,
66
+                        created_by: true,
67
+                    },
68
+                },
69
+                status: true,
70
+                simrs_type: true,
71
+                contract_value_min: true,
72
+                contract_value_max: true,
73
+                contract_start_date: true,
74
+                contract_expired_date: true,
75
+                positive_notes: true,
76
+                negative_notes: true,
77
+                createdAt: true,
78
+                updatedAt: true,
79
+            },
80
+        });
81
+    },
82
+
83
+    create: async (data: Prisma.VendorExperienceCreateInput) => {
84
+        return prisma.vendorExperience.create({ data });
85
+    },
86
+
87
+    update: async (id: string, data: Prisma.VendorExperienceUpdateInput) => {
88
+        return prisma.vendorExperience.update({
89
+            where: { id },
90
+            data,
91
+        });
92
+    },
93
+};
94
+
95
+export default VendorExperienceRepository;
96
+
97
+// const prisma = require('../../prisma/PrismaClient.js');
98
+
99
+// const VendorExperienceRepository = {
100
+//     findAll: async ({ skip, take, where, orderBy }) => {
101
+//         return prisma.vendorExperience.findMany({
102
+//             where,
103
+//             skip,
104
+//             take,
105
+//             orderBy,
106
+//             select: {
107
+//                 id: true,
108
+//                 // hospital: {
109
+//                 //     select: {
110
+//                 //         id: true,
111
+//                 //         name: true,
112
+//                 //         hospital_code: true,
113
+//                 //         type: true,
114
+//                 //         ownership: true,
115
+//                 //         province: {
116
+//                 //             select: {
117
+//                 //                 id: true,
118
+//                 //                 name: true
119
+//                 //             }
120
+//                 //         },
121
+//                 //         city: {
122
+//                 //             select: {
123
+//                 //                 id: true,
124
+//                 //                 name: true
125
+//                 //             }
126
+//                 //         },
127
+//                 //         address: true,
128
+//                 //         simrs_type: true,
129
+//                 //         contact: true,
130
+//                 //         image: true,
131
+//                 //         progress_status: true,
132
+//                 //         note: true,
133
+//                 //         created_by: true
134
+//                 //     }
135
+//                 // },
136
+//                 vendor: {
137
+//                     select: {
138
+//                         id: true,
139
+//                         name: true,
140
+//                         name_pt: true,
141
+//                         strengths: true,
142
+//                         weaknesses: true,
143
+//                         website: true,
144
+//                         created_by: true,
145
+//                     }
146
+//                 },
147
+//                 status: true,
148
+//                 simrs_type: true,
149
+//                 contract_value_min: true,
150
+//                 contract_value_max: true,
151
+//                 contract_start_date: true,
152
+//                 contract_expired_date: true,
153
+//                 positive_notes: true,
154
+//                 negative_notes: true,
155
+//                 createdAt: true,
156
+//                 updatedAt: true,
157
+//             },
158
+//         });
159
+//     },
160
+
161
+//     countAll: async (where) => {
162
+//         return prisma.vendorExperience.count({ where });
163
+//     },
164
+
165
+//     findById: async (id) => {
166
+//         return prisma.vendorExperience.findFirst({
167
+//             where: {
168
+//                 id,
169
+//                 deletedAt: null
170
+//             },
171
+//             select: {
172
+//                 id: true,
173
+//                 // hospital: {
174
+//                 //     select: {
175
+//                 //         id: true,
176
+//                 //         name: true,
177
+//                 //         hospital_code: true,
178
+//                 //         type: true,
179
+//                 //         ownership: true,
180
+//                 //         province: {
181
+//                 //             select: {
182
+//                 //                 id: true,
183
+//                 //                 name: true
184
+//                 //             }
185
+//                 //         },
186
+//                 //         city: {
187
+//                 //             select: {
188
+//                 //                 id: true,
189
+//                 //                 name: true
190
+//                 //             }
191
+//                 //         },
192
+//                 //         address: true,
193
+//                 //         simrs_type: true,
194
+//                 //         contact: true,
195
+//                 //         image: true,
196
+//                 //         progress_status: true,
197
+//                 //         note: true,
198
+//                 //         created_by: true
199
+//                 //     }
200
+//                 // },
201
+//                 vendor: {
202
+//                     select: {
203
+//                         id: true,
204
+//                         name: true,
205
+//                         name_pt: true,
206
+//                         strengths: true,
207
+//                         weaknesses: true,
208
+//                         website: true,
209
+//                         created_by: true,
210
+//                     }
211
+//                 },
212
+//                 status: true,
213
+//                 simrs_type: true,
214
+//                 contract_value_min: true,
215
+//                 contract_value_max: true,
216
+//                 contract_start_date: true,
217
+//                 contract_expired_date: true,
218
+//                 positive_notes: true,
219
+//                 negative_notes: true,
220
+//                 createdAt: true,
221
+//                 updatedAt: true,
222
+//             },
223
+//         });
224
+//     },
225
+
226
+//     create: async (data) => {
227
+//         return prisma.vendorExperience.create({ data });
228
+//     },
229
+
230
+//     update: async (id, data) => {
231
+//         return prisma.vendorExperience.update({
232
+//             where: { id },
233
+//             data
234
+//         });
235
+//     },
236
+// };
237
+
238
+// module.exports = VendorExperienceRepository;

+ 0 - 118
src/repository/admin/VendorRepository.js

@@ -1,118 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-const timeLocal = require('../../utils/TimeLocal.js');
3
-
4
-const VendorRepository = {
5
-    findAll: async ({ skip, take, where, orderBy }) => {
6
-        const vendors = await prisma.vendor.findMany({
7
-            where,
8
-            skip,
9
-            take,
10
-            orderBy,
11
-            select: {
12
-                id: true,
13
-                name: true,
14
-                name_pt: true,
15
-                strengths: true,
16
-                weaknesses: true,
17
-                website: true,
18
-                created_by: true,
19
-                _count: {
20
-                    select: {
21
-                        vendor_experiences: {
22
-                            where: {
23
-                                deletedAt: null
24
-                            }
25
-                        }
26
-                    }
27
-                },
28
-                createdAt: true,
29
-                updatedAt: true,
30
-            },
31
-        });
32
-
33
-        const formattedVendors = vendors.map(v => {
34
-            const { _count, ...rest } = v;
35
-            return {
36
-                ...rest,
37
-                count_hospitals: _count.vendor_experiences,
38
-            };
39
-        });
40
-
41
-        return formattedVendors;
42
-    },
43
-
44
-    countAll: async (where) => {
45
-        return prisma.vendor.count({ where });
46
-    },
47
-
48
-    findById: async (id) => {
49
-        const vendor = await prisma.vendor.findFirst({
50
-            where: {
51
-                id,
52
-                deletedAt: null
53
-            },
54
-            select: {
55
-                id: true,
56
-                name: true,
57
-                name_pt: true,
58
-                strengths: true,
59
-                weaknesses: true,
60
-                website: true,
61
-                created_by: true,
62
-                _count: {
63
-                    select: {
64
-                        vendor_experiences: {
65
-                            where: {
66
-                                deletedAt: null
67
-                            }
68
-                        }
69
-                    }
70
-                },
71
-                createdAt: true,
72
-                updatedAt: true,
73
-            },
74
-        });
75
-
76
-        const { _count, ...rest } = vendor;
77
-        return {
78
-            ...rest,
79
-            count_hospitals: _count.vendor_experiences
80
-        };
81
-    },
82
-
83
-    create: async (data) => {
84
-        return prisma.vendor.create({ data });
85
-    },
86
-
87
-    update: async (id, data) => {
88
-        return prisma.vendor.update({
89
-            where: { id },
90
-            data
91
-        });
92
-    },
93
-
94
-    delete: async (id) => {
95
-        // delete vendor
96
-        const vendor = await prisma.vendor.update({
97
-            where: { id },
98
-            data: {
99
-                deletedAt: timeLocal.now().toDate()
100
-            }
101
-        });
102
-
103
-        // Unlink vendor_id di vendor_histories
104
-        await prisma.vendorExperience.updateMany({
105
-            where: {
106
-                vendor_id: id,
107
-                deletedAt: null
108
-            },
109
-            data: {
110
-                vendor_id: null
111
-            }
112
-        });
113
-
114
-        return vendor;
115
-    },
116
-};
117
-
118
-module.exports = VendorRepository;

+ 247 - 0
src/repository/admin/VendorRepository.ts

@@ -0,0 +1,247 @@
1
+import prisma from '../../prisma/PrismaClient';
2
+import { now } from '../../utils/TimeLocal';
3
+import { Prisma } from '@prisma/client';
4
+
5
+type FindAllOptions = {
6
+    skip?: number;
7
+    take?: number;
8
+    where?: Prisma.VendorWhereInput;
9
+    orderBy?: Prisma.VendorOrderByWithRelationInput;
10
+};
11
+
12
+const VendorRepository = {
13
+    findAll: async ({ skip, take, where, orderBy }: FindAllOptions) => {
14
+        const vendors = await prisma.vendor.findMany({
15
+            where,
16
+            skip,
17
+            take,
18
+            orderBy,
19
+            select: {
20
+                id: true,
21
+                name: true,
22
+                name_pt: true,
23
+                strengths: true,
24
+                weaknesses: true,
25
+                website: true,
26
+                user: { select: { id: true, fullname: true } },
27
+                _count: {
28
+                    select: {
29
+                        vendor_experiences: {
30
+                            where: {
31
+                                deletedAt: null,
32
+                                status: "active"
33
+                            },
34
+                        },
35
+                    },
36
+                },
37
+                createdAt: true,
38
+                updatedAt: true,
39
+            },
40
+        });
41
+
42
+        const formattedVendors = vendors.map(v => {
43
+            const { _count, ...rest } = v;
44
+            return {
45
+                ...rest,
46
+                count_hospitals: _count.vendor_experiences,
47
+            };
48
+        });
49
+
50
+        return formattedVendors;
51
+    },
52
+
53
+    countAll: async (where?: Prisma.VendorWhereInput) => {
54
+        return prisma.vendor.count({ where });
55
+    },
56
+
57
+    findById: async (id: string) => {
58
+        const vendor = await prisma.vendor.findFirst({
59
+            where: {
60
+                id,
61
+                deletedAt: null,
62
+            },
63
+            select: {
64
+                id: true,
65
+                name: true,
66
+                name_pt: true,
67
+                strengths: true,
68
+                weaknesses: true,
69
+                website: true,
70
+                user: { select: { id: true, fullname: true } },
71
+                _count: {
72
+                    select: {
73
+                        vendor_experiences: {
74
+                            where: {
75
+                                deletedAt: null,
76
+                            },
77
+                        },
78
+                    },
79
+                },
80
+                createdAt: true,
81
+                updatedAt: true,
82
+            },
83
+        });
84
+
85
+        if (!vendor) return null;
86
+
87
+        const { _count, ...rest } = vendor;
88
+        return {
89
+            ...rest,
90
+            count_hospitals: _count.vendor_experiences,
91
+        };
92
+    },
93
+
94
+    create: async (data: Prisma.VendorCreateInput) => {
95
+        return prisma.vendor.create({ data });
96
+    },
97
+
98
+    update: async (id: string, data: Prisma.VendorUpdateInput) => {
99
+        return prisma.vendor.update({
100
+            where: { id },
101
+            data,
102
+        });
103
+    },
104
+
105
+    delete: async (id: string) => {
106
+        const vendor = await prisma.vendor.update({
107
+            where: { id },
108
+            data: {
109
+                deletedAt: now().toDate(),
110
+            },
111
+        });
112
+
113
+        await prisma.vendorExperience.updateMany({
114
+            where: {
115
+                vendor_id: id,
116
+                deletedAt: null,
117
+            },
118
+            data: {
119
+                vendor_id: null,
120
+            },
121
+        });
122
+
123
+        return vendor;
124
+    },
125
+};
126
+
127
+export default VendorRepository;
128
+
129
+
130
+// const prisma = require('../../prisma/PrismaClient.js');
131
+// const timeLocal = require('../../utils/TimeLocal.js');
132
+
133
+// const VendorRepository = {
134
+//     findAll: async ({ skip, take, where, orderBy }) => {
135
+//         const vendors = await prisma.vendor.findMany({
136
+//             where,
137
+//             skip,
138
+//             take,
139
+//             orderBy,
140
+//             select: {
141
+//                 id: true,
142
+//                 name: true,
143
+//                 name_pt: true,
144
+//                 strengths: true,
145
+//                 weaknesses: true,
146
+//                 website: true,
147
+//                 user: { select: { id: true, fullname: true } },
148
+//                 _count: {
149
+//                     select: {
150
+//                         vendor_experiences: {
151
+//                             where: {
152
+//                                 deletedAt: null
153
+//                             }
154
+//                         }
155
+//                     }
156
+//                 },
157
+//                 createdAt: true,
158
+//                 updatedAt: true,
159
+//             },
160
+//         });
161
+
162
+//         const formattedVendors = vendors.map(v => {
163
+//             const { _count, ...rest } = v;
164
+//             return {
165
+//                 ...rest,
166
+//                 count_hospitals: _count.vendor_experiences,
167
+//             };
168
+//         });
169
+
170
+//         return formattedVendors;
171
+//     },
172
+
173
+//     countAll: async (where) => {
174
+//         return prisma.vendor.count({ where });
175
+//     },
176
+
177
+//     findById: async (id) => {
178
+//         const vendor = await prisma.vendor.findFirst({
179
+//             where: {
180
+//                 id,
181
+//                 deletedAt: null
182
+//             },
183
+//             select: {
184
+//                 id: true,
185
+//                 name: true,
186
+//                 name_pt: true,
187
+//                 strengths: true,
188
+//                 weaknesses: true,
189
+//                 website: true,
190
+//                 user: { select: { id: true, fullname: true } },
191
+//                 _count: {
192
+//                     select: {
193
+//                         vendor_experiences: {
194
+//                             where: {
195
+//                                 deletedAt: null
196
+//                             }
197
+//                         }
198
+//                     }
199
+//                 },
200
+//                 createdAt: true,
201
+//                 updatedAt: true,
202
+//             },
203
+//         });
204
+
205
+//         const { _count, ...rest } = vendor;
206
+//         return {
207
+//             ...rest,
208
+//             count_hospitals: _count.vendor_experiences
209
+//         };
210
+//     },
211
+
212
+//     create: async (data) => {
213
+//         return prisma.vendor.create({ data });
214
+//     },
215
+
216
+//     update: async (id, data) => {
217
+//         return prisma.vendor.update({
218
+//             where: { id },
219
+//             data
220
+//         });
221
+//     },
222
+
223
+//     delete: async (id) => {
224
+//         // delete vendor
225
+//         const vendor = await prisma.vendor.update({
226
+//             where: { id },
227
+//             data: {
228
+//                 deletedAt: timeLocal.now().toDate()
229
+//             }
230
+//         });
231
+
232
+//         // Unlink vendor_id di vendor_histories
233
+//         await prisma.vendorExperience.updateMany({
234
+//             where: {
235
+//                 vendor_id: id,
236
+//                 deletedAt: null
237
+//             },
238
+//             data: {
239
+//                 vendor_id: null
240
+//             }
241
+//         });
242
+
243
+//         return vendor;
244
+//     },
245
+// };
246
+
247
+// module.exports = VendorRepository;

+ 0 - 28
src/repository/sales/AreaRepository.js

@@ -1,28 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const AreaRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return await prisma.userArea.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                user_id: true,
13
-                province: {
14
-                    select: {
15
-                        id: true,
16
-                        name: true
17
-                    }
18
-                },
19
-            }
20
-        });
21
-    },
22
-
23
-    countAll: async (where) => {
24
-        return prisma.userArea.count({ where });
25
-    },
26
-};
27
-
28
-module.exports = AreaRepository;

+ 66 - 0
src/repository/sales/AreaRepository.ts

@@ -0,0 +1,66 @@
1
+// AreaRepository.ts
2
+import prisma from '../../prisma/PrismaClient';
3
+import { Prisma } from '@prisma/client';
4
+
5
+interface FindAllParams {
6
+    skip?: number;
7
+    take?: number;
8
+    where?: Prisma.UserAreaWhereInput;
9
+    orderBy?: Prisma.UserAreaOrderByWithRelationInput;
10
+}
11
+
12
+const AreaRepository = {
13
+    findAll: async ({ skip, take, where, orderBy }: FindAllParams) => {
14
+        return await prisma.userArea.findMany({
15
+            where,
16
+            skip,
17
+            take,
18
+            orderBy,
19
+            select: {
20
+                id: true,
21
+                province: {
22
+                    select: {
23
+                        id: true,
24
+                        name: true,
25
+                    },
26
+                },
27
+                createdAt: true,
28
+                updatedAt: true
29
+            },
30
+        });
31
+    },
32
+
33
+    countAll: async (where?: Prisma.UserAreaWhereInput) => {
34
+        return prisma.userArea.count({ where });
35
+    },
36
+};
37
+
38
+export default AreaRepository;
39
+
40
+// const prisma = require('../../prisma/PrismaClient.js');
41
+
42
+// const AreaRepository = {
43
+//     findAll: async ({ skip, take, where, orderBy }) => {
44
+//         return await prisma.userArea.findMany({
45
+//             where,
46
+//             skip,
47
+//             take,
48
+//             orderBy,
49
+//             select: {
50
+//                 id: true,
51
+//                 province: {
52
+//                     select: {
53
+//                         id: true,
54
+//                         name: true
55
+//                     }
56
+//                 },
57
+//             }
58
+//         });
59
+//     },
60
+
61
+//     countAll: async (where) => {
62
+//         return prisma.userArea.count({ where });
63
+//     },
64
+// };
65
+
66
+// module.exports = AreaRepository;

+ 0 - 120
src/repository/sales/ExecutivesHistoryRepository.js

@@ -1,120 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const ExecutivesHistoryRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.executivesHistory.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                hospital: {
13
-                    select: {
14
-                        id: true,
15
-                        name: true,
16
-                        hospital_code: true,
17
-                        type: true,
18
-                        ownership: true,
19
-                        province: {
20
-                            select: {
21
-                                id: true,
22
-                                name: true
23
-                            }
24
-                        },
25
-                        city: {
26
-                            select: {
27
-                                id: true,
28
-                                name: true
29
-                            }
30
-                        },
31
-                        address: true,
32
-                        simrs_type: true,
33
-                        contact: true,
34
-                        image: true,
35
-                        progress_status: true,
36
-                        note: true,
37
-                        // user: {
38
-                        //     select: {
39
-                        //         id: true,
40
-                        //         username: true
41
-                        //     }
42
-                        // }
43
-                        created_by: true
44
-                    }
45
-                },
46
-                executive_name: true,
47
-                contact: true,
48
-                status: true,
49
-                start_term: true,
50
-                end_term: true,
51
-                createdAt: true,
52
-                updatedAt: true,
53
-            },
54
-        });
55
-    },
56
-
57
-    countAll: async (where) => {
58
-        return prisma.executivesHistory.count({ where });
59
-    },
60
-
61
-    findById: async (id) => {
62
-        return prisma.executivesHistory.findFirst({
63
-            where: {
64
-                id,
65
-                deletedAt: null
66
-            },
67
-            select: {
68
-                id: true,
69
-                hospital: {
70
-                    select: {
71
-                        id: true,
72
-                        name: true,
73
-                        hospital_code: true,
74
-                        type: true,
75
-                        ownership: true,
76
-                        province: {
77
-                            select: {
78
-                                id: true,
79
-                                name: true
80
-                            }
81
-                        },
82
-                        city: {
83
-                            select: {
84
-                                id: true,
85
-                                name: true
86
-                            }
87
-                        },
88
-                        address: true,
89
-                        simrs_type: true,
90
-                        contact: true,
91
-                        image: true,
92
-                        progress_status: true,
93
-                        note: true,
94
-                        created_by: true
95
-                    }
96
-                },
97
-                executive_name: true,
98
-                contact: true,
99
-                status: true,
100
-                start_term: true,
101
-                end_term: true,
102
-                createdAt: true,
103
-                updatedAt: true,
104
-            },
105
-        });
106
-    },
107
-
108
-    create: async (data) => {
109
-        return prisma.executivesHistory.create({ data });
110
-    },
111
-
112
-    update: async (id, data) => {
113
-        return prisma.executivesHistory.update({
114
-            where: { id },
115
-            data
116
-        });
117
-    },
118
-};
119
-
120
-module.exports = ExecutivesHistoryRepository;

+ 189 - 0
src/repository/sales/ExecutivesHistoryRepository.ts

@@ -0,0 +1,189 @@
1
+import { PrismaClient, Prisma } from '@prisma/client';
2
+
3
+const prisma = new PrismaClient();
4
+
5
+export const ExecutivesHistoryRepository = {
6
+    findAll: async ({
7
+        skip,
8
+        take,
9
+        where,
10
+        orderBy
11
+    }: {
12
+        skip?: number;
13
+        take?: number;
14
+        where?: Prisma.ExecutivesHistoryWhereInput;
15
+        orderBy?: Prisma.ExecutivesHistoryOrderByWithRelationInput;
16
+    }) => {
17
+        return prisma.executivesHistory.findMany({
18
+            where,
19
+            skip,
20
+            take,
21
+            orderBy,
22
+            select: {
23
+                id: true,
24
+                executive_name: true,
25
+                contact: true,
26
+                status: true,
27
+                start_term: true,
28
+                end_term: true,
29
+                createdAt: true,
30
+                updatedAt: true,
31
+            },
32
+        });
33
+    },
34
+
35
+    countAll: async (where?: Prisma.ExecutivesHistoryWhereInput) => {
36
+        return prisma.executivesHistory.count({ where });
37
+    },
38
+
39
+    findById: async (id: string) => {
40
+        return prisma.executivesHistory.findFirst({
41
+            where: {
42
+                id,
43
+                deletedAt: null,
44
+            },
45
+            select: {
46
+                id: true,
47
+                executive_name: true,
48
+                contact: true,
49
+                status: true,
50
+                start_term: true,
51
+                end_term: true,
52
+                createdAt: true,
53
+                updatedAt: true,
54
+            },
55
+        });
56
+    },
57
+
58
+    create: async (data: Prisma.ExecutivesHistoryCreateInput) => {
59
+        return prisma.executivesHistory.create({ data });
60
+    },
61
+
62
+    update: async (id: string, data: Prisma.ExecutivesHistoryUpdateInput) => {
63
+        return prisma.executivesHistory.update({
64
+            where: { id },
65
+            data,
66
+        });
67
+    },
68
+};
69
+
70
+// const prisma = require('../../prisma/PrismaClient.js');
71
+
72
+// const ExecutivesHistoryRepository = {
73
+//     findAll: async ({ skip, take, where, orderBy }) => {
74
+//         return prisma.executivesHistory.findMany({
75
+//             where,
76
+//             skip,
77
+//             take,
78
+//             orderBy,
79
+//             select: {
80
+//                 id: true,
81
+//                 hospital: {
82
+//                     select: {
83
+//                         id: true,
84
+//                         name: true,
85
+//                         hospital_code: true,
86
+//                         type: true,
87
+//                         ownership: true,
88
+//                         province: {
89
+//                             select: {
90
+//                                 id: true,
91
+//                                 name: true
92
+//                             }
93
+//                         },
94
+//                         city: {
95
+//                             select: {
96
+//                                 id: true,
97
+//                                 name: true
98
+//                             }
99
+//                         },
100
+//                         address: true,
101
+//                         // simrs_type: true,
102
+//                         contact: true,
103
+//                         image: true,
104
+//                         progress_status: true,
105
+//                         note: true,
106
+//                         // user: {
107
+//                         //     select: {
108
+//                         //         id: true,
109
+//                         //         username: true
110
+//                         //     }
111
+//                         // }
112
+//                         created_by: true
113
+//                     }
114
+//                 },
115
+//                 executive_name: true,
116
+//                 contact: true,
117
+//                 status: true,
118
+//                 start_term: true,
119
+//                 end_term: true,
120
+//                 createdAt: true,
121
+//                 updatedAt: true,
122
+//             },
123
+//         });
124
+//     },
125
+
126
+//     countAll: async (where) => {
127
+//         return prisma.executivesHistory.count({ where });
128
+//     },
129
+
130
+//     findById: async (id) => {
131
+//         return prisma.executivesHistory.findFirst({
132
+//             where: {
133
+//                 id,
134
+//                 deletedAt: null
135
+//             },
136
+//             select: {
137
+//                 id: true,
138
+//                 hospital: {
139
+//                     select: {
140
+//                         id: true,
141
+//                         name: true,
142
+//                         hospital_code: true,
143
+//                         type: true,
144
+//                         ownership: true,
145
+//                         province: {
146
+//                             select: {
147
+//                                 id: true,
148
+//                                 name: true
149
+//                             }
150
+//                         },
151
+//                         city: {
152
+//                             select: {
153
+//                                 id: true,
154
+//                                 name: true
155
+//                             }
156
+//                         },
157
+//                         address: true,
158
+//                         // simrs_type: true,
159
+//                         contact: true,
160
+//                         image: true,
161
+//                         progress_status: true,
162
+//                         note: true,
163
+//                         created_by: true
164
+//                     }
165
+//                 },
166
+//                 executive_name: true,
167
+//                 contact: true,
168
+//                 status: true,
169
+//                 start_term: true,
170
+//                 end_term: true,
171
+//                 createdAt: true,
172
+//                 updatedAt: true,
173
+//             },
174
+//         });
175
+//     },
176
+
177
+//     create: async (data) => {
178
+//         return prisma.executivesHistory.create({ data });
179
+//     },
180
+
181
+//     update: async (id, data) => {
182
+//         return prisma.executivesHistory.update({
183
+//             where: { id },
184
+//             data
185
+//         });
186
+//     },
187
+// };
188
+
189
+// module.exports = ExecutivesHistoryRepository;

+ 0 - 152
src/repository/sales/HospitalRepository.js

@@ -1,152 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const HospitalRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        const hospitalsRaw = await prisma.hospital.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                name: true,
13
-                hospital_code: true,
14
-                type: true,
15
-                ownership: true,
16
-                province: { select: { id: true, name: true } },
17
-                city: { select: { id: true, name: true } },
18
-                address: true,
19
-                simrs_type: true,
20
-                contact: true,
21
-                image: true,
22
-                progress_status: true,
23
-                note: true,
24
-                latitude: true,
25
-                longitude: true,
26
-                gmaps_url: true,
27
-                created_by: true,
28
-                createdAt: true,
29
-                updatedAt: true,
30
-                vendor_histories: {
31
-                    where: {
32
-                        status: "active",
33
-                        deletedAt: null
34
-                    },
35
-                    select: {
36
-                        vendor: {
37
-                            select: {
38
-                                id: true,
39
-                                name: true,
40
-                                name_pt: true,
41
-                                strengths: true,
42
-                                weaknesses: true,
43
-                                website: true,
44
-                            }
45
-                        }
46
-                    }
47
-                }
48
-            }
49
-        });
50
-
51
-        return hospitalsRaw.map(hospital => {
52
-            const { vendor_histories, ...rest } = hospital;
53
-            return {
54
-                ...rest,
55
-                vendor: vendor_histories?.[0]?.vendor || null
56
-            };
57
-        });
58
-    },
59
-
60
-    countAll: async (where) => {
61
-        return prisma.hospital.count({ where });
62
-    },
63
-
64
-    create: async (data) => {
65
-        return prisma.hospital.create({ data });
66
-    },
67
-
68
-    findById: async (id) => {
69
-        const hospitalRaw = await prisma.hospital.findFirst({
70
-            where: {
71
-                id,
72
-                deletedAt: null
73
-            },
74
-            select: {
75
-                id: true,
76
-                name: true,
77
-                hospital_code: true,
78
-                type: true,
79
-                ownership: true,
80
-                province: { select: { id: true, name: true } },
81
-                city: { select: { id: true, name: true } },
82
-                address: true,
83
-                simrs_type: true,
84
-                contact: true,
85
-                image: true,
86
-                progress_status: true,
87
-                note: true,
88
-                latitude: true,
89
-                longitude: true,
90
-                gmaps_url: true,
91
-                created_by: true,
92
-                createdAt: true,
93
-                updatedAt: true,
94
-                vendor_histories: {
95
-                    where: {
96
-                        status: "active",
97
-                        deletedAt: null
98
-                    },
99
-                    take: 1,
100
-                    select: {
101
-                        vendor: {
102
-                            select: {
103
-                                id: true,
104
-                                name: true,
105
-                                name_pt: true,
106
-                                strengths: true,
107
-                                weaknesses: true,
108
-                                website: true,
109
-                            }
110
-                        }
111
-                    }
112
-                }
113
-            }
114
-        });
115
-
116
-        if (!hospitalRaw) return null;
117
-
118
-        const { vendor_histories, ...rest } = hospitalRaw;
119
-        return {
120
-            ...rest,
121
-            vendor: vendor_histories?.[0]?.vendor || null
122
-        };
123
-    },
124
-
125
-    // update: async (id, data) => {
126
-    //     return prisma.hospital.update({
127
-    //         where: { id },
128
-    //         data: {
129
-    //             name: data.name,
130
-    //             hospital_code: data.hospital_code,
131
-    //             type: data.type,
132
-    //             ownership: data.ownership,
133
-    //             province: { connect: { id: data.province_id } },
134
-    //             city: { connect: { id: data.city_id } },
135
-    //             address: data.address,
136
-    //             // simrs_type: data.simrs_type,
137
-    //             contact: data.contact,
138
-    //             note: data.note,
139
-    //             image: data.image,
140
-    //             progress_status: data.progress_status,
141
-    //         }
142
-    //     });
143
-    // },
144
-    update: async (id, data) => {
145
-        return prisma.hospital.update({
146
-            where: { id },
147
-            data
148
-        });
149
-    },
150
-};
151
-
152
-module.exports = HospitalRepository;

+ 276 - 0
src/repository/sales/HospitalRepository.ts

@@ -0,0 +1,276 @@
1
+import prisma from '../../prisma/PrismaClient';
2
+import { Prisma } from '@prisma/client';
3
+
4
+interface FindAllParams {
5
+    skip?: number;
6
+    take?: number;
7
+    where?: Prisma.HospitalWhereInput;
8
+    orderBy?: Prisma.HospitalOrderByWithRelationInput;
9
+}
10
+
11
+const HospitalRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllParams) => {
13
+        const hospitalsRaw = await prisma.hospital.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                name: true,
21
+                hospital_code: true,
22
+                type: true,
23
+                ownership: true,
24
+                province: { select: { id: true, name: true } },
25
+                city: { select: { id: true, name: true } },
26
+                address: true,
27
+                contact: true,
28
+                image: true,
29
+                progress_status: true,
30
+                note: true,
31
+                latitude: true,
32
+                longitude: true,
33
+                gmaps_url: true,
34
+                // created_by: true,
35
+                createdAt: true,
36
+                updatedAt: true,
37
+                user: { select: { id: true, fullname: true } },
38
+                vendor_experiences: {
39
+                    where: {
40
+                        status: 'active',
41
+                        deletedAt: null,
42
+                    },
43
+                    select: {
44
+                        vendor: {
45
+                            select: {
46
+                                id: true,
47
+                                name: true,
48
+                                name_pt: true,
49
+                                strengths: true,
50
+                                weaknesses: true,
51
+                                website: true,
52
+                            },
53
+                        },
54
+                    },
55
+                },
56
+            },
57
+        });
58
+
59
+        return hospitalsRaw.map(hospital => {
60
+            const { vendor_experiences, ...rest } = hospital;
61
+            return {
62
+                ...rest,
63
+                vendor: vendor_experiences?.[0]?.vendor || null,
64
+            };
65
+        });
66
+    },
67
+
68
+    countAll: async (where?: Prisma.HospitalWhereInput) => {
69
+        return prisma.hospital.count({ where });
70
+    },
71
+
72
+    create: async (data: Prisma.HospitalCreateInput) => {
73
+        return prisma.hospital.create({ data });
74
+    },
75
+
76
+    findById: async (id: string) => {
77
+        const hospitalRaw = await prisma.hospital.findFirst({
78
+            where: {
79
+                id,
80
+                deletedAt: null,
81
+            },
82
+            select: {
83
+                id: true,
84
+                name: true,
85
+                hospital_code: true,
86
+                type: true,
87
+                ownership: true,
88
+                province: { select: { id: true, name: true } },
89
+                city: { select: { id: true, name: true } },
90
+                address: true,
91
+                contact: true,
92
+                image: true,
93
+                progress_status: true,
94
+                note: true,
95
+                latitude: true,
96
+                longitude: true,
97
+                gmaps_url: true,
98
+                created_by: true,
99
+                createdAt: true,
100
+                updatedAt: true,
101
+                user: { select: { id: true, fullname: true } },
102
+                vendor_experiences: {
103
+                    where: {
104
+                        status: 'active',
105
+                        deletedAt: null,
106
+                    },
107
+                    take: 1,
108
+                    select: {
109
+                        vendor: {
110
+                            select: {
111
+                                id: true,
112
+                                name: true,
113
+                                name_pt: true,
114
+                                strengths: true,
115
+                                weaknesses: true,
116
+                                website: true,
117
+                            },
118
+                        },
119
+                    },
120
+                },
121
+            },
122
+        });
123
+
124
+        if (!hospitalRaw) return null;
125
+
126
+        const { vendor_experiences, ...rest } = hospitalRaw;
127
+        return {
128
+            ...rest,
129
+            vendor: vendor_experiences?.[0]?.vendor || null,
130
+        };
131
+    },
132
+
133
+    update: async (id: string, data: Prisma.HospitalUpdateInput) => {
134
+        return prisma.hospital.update({
135
+            where: { id },
136
+            data,
137
+        });
138
+    },
139
+};
140
+
141
+export default HospitalRepository;
142
+
143
+
144
+// const prisma = require('../../prisma/PrismaClient.js');
145
+
146
+// const HospitalRepository = {
147
+//     findAll: async ({ skip, take, where, orderBy }) => {
148
+//         const hospitalsRaw = await prisma.hospital.findMany({
149
+//             where,
150
+//             skip,
151
+//             take,
152
+//             orderBy,
153
+//             select: {
154
+//                 id: true,
155
+//                 name: true,
156
+//                 hospital_code: true,
157
+//                 type: true,
158
+//                 ownership: true,
159
+//                 province: { select: { id: true, name: true } },
160
+//                 city: { select: { id: true, name: true } },
161
+//                 address: true,
162
+//                 contact: true,
163
+//                 image: true,
164
+//                 progress_status: true,
165
+//                 note: true,
166
+//                 latitude: true,
167
+//                 longitude: true,
168
+//                 gmaps_url: true,
169
+//                 created_by: true,
170
+//                 createdAt: true,
171
+//                 updatedAt: true,
172
+//                 user: { select: { id: true, fullname: true } },
173
+//                 vendor_experiences: {
174
+//                     where: {
175
+//                         status: "active",
176
+//                         deletedAt: null
177
+//                     },
178
+//                     select: {
179
+//                         vendor: {
180
+//                             select: {
181
+//                                 id: true,
182
+//                                 name: true,
183
+//                                 name_pt: true,
184
+//                                 strengths: true,
185
+//                                 weaknesses: true,
186
+//                                 website: true,
187
+//                             }
188
+//                         }
189
+//                     }
190
+//                 }
191
+//             }
192
+//         });
193
+
194
+//         return hospitalsRaw.map(hospital => {
195
+//             const { vendor_experiences, ...rest } = hospital;
196
+//             return {
197
+//                 ...rest,
198
+//                 vendor: vendor_experiences?.[0]?.vendor || null
199
+//             };
200
+//         });
201
+//     },
202
+
203
+//     countAll: async (where) => {
204
+//         return prisma.hospital.count({ where });
205
+//     },
206
+
207
+//     create: async (data) => {
208
+//         return prisma.hospital.create({ data });
209
+//     },
210
+
211
+//     findById: async (id) => {
212
+//         const hospitalRaw = await prisma.hospital.findFirst({
213
+//             where: {
214
+//                 id,
215
+//                 deletedAt: null
216
+//             },
217
+//             select: {
218
+//                 id: true,
219
+//                 name: true,
220
+//                 hospital_code: true,
221
+//                 type: true,
222
+//                 ownership: true,
223
+//                 province: { select: { id: true, name: true } },
224
+//                 city: { select: { id: true, name: true } },
225
+//                 address: true,
226
+//                 contact: true,
227
+//                 image: true,
228
+//                 progress_status: true,
229
+//                 note: true,
230
+//                 latitude: true,
231
+//                 longitude: true,
232
+//                 gmaps_url: true,
233
+//                 created_by: true,
234
+//                 createdAt: true,
235
+//                 updatedAt: true,
236
+//                 user: { select: { id: true, fullname: true } },
237
+//                 vendor_experiences: {
238
+//                     where: {
239
+//                         status: "active",
240
+//                         deletedAt: null
241
+//                     },
242
+//                     take: 1,
243
+//                     select: {
244
+//                         vendor: {
245
+//                             select: {
246
+//                                 id: true,
247
+//                                 name: true,
248
+//                                 name_pt: true,
249
+//                                 strengths: true,
250
+//                                 weaknesses: true,
251
+//                                 website: true,
252
+//                             }
253
+//                         }
254
+//                     }
255
+//                 }
256
+//             }
257
+//         });
258
+
259
+//         if (!hospitalRaw) return null;
260
+
261
+//         const { vendor_experiences, ...rest } = hospitalRaw;
262
+//         return {
263
+//             ...rest,
264
+//             vendor: vendor_experiences?.[0]?.vendor || null
265
+//         };
266
+//     },
267
+
268
+//     update: async (id, data) => {
269
+//         return prisma.hospital.update({
270
+//             where: { id },
271
+//             data
272
+//         });
273
+//     },
274
+// };
275
+
276
+// module.exports = HospitalRepository;

+ 0 - 70
src/repository/sales/StatusHistoryRepository.js

@@ -1,70 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const StatusHistoryRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.statusHistory.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                hospital: {
13
-                    select: {
14
-                        id: true,
15
-                        name: true,
16
-                        // hospital_code: true,
17
-                        // type: true,
18
-                        // ownership: true,
19
-                        // province: {
20
-                        //     select: {
21
-                        //         id: true,
22
-                        //         name: true
23
-                        //     }
24
-                        // },
25
-                        // city: {
26
-                        //     select: {
27
-                        //         id: true,
28
-                        //         name: true
29
-                        //     }
30
-                        // },
31
-                        // address: true,
32
-                        // simrs_type: true,
33
-                        // contact: true,
34
-                        // image: true,
35
-                        progress_status: true,
36
-                        // note: true,
37
-                        // user: {
38
-                        //     select: {
39
-                        //         id: true,
40
-                        //         username: true
41
-                        //     }
42
-                        // }
43
-                    }
44
-                },
45
-                // user: {
46
-                //     select: {
47
-                //         id: true,
48
-                //         username: true,
49
-                //     }
50
-                // },
51
-                user_id: true,
52
-                old_status: true,
53
-                new_status: true,
54
-                note: true,
55
-                createdAt: true,
56
-                updatedAt: true,
57
-            },
58
-        });
59
-    },
60
-
61
-    countAll: async (where) => {
62
-        return prisma.statusHistory.count({ where });
63
-    },
64
-
65
-    create: async (data) => {
66
-        return prisma.statusHistory.create({ data });
67
-    },
68
-};
69
-
70
-module.exports = StatusHistoryRepository;

+ 115 - 0
src/repository/sales/StatusHistoryRepository.ts

@@ -0,0 +1,115 @@
1
+import { Prisma } from '@prisma/client';
2
+import prisma from '../../prisma/PrismaClient';
3
+
4
+type FindAllArgs = {
5
+    skip: number;
6
+    take: number;
7
+    where: Prisma.StatusHistoryWhereInput;
8
+    orderBy: Prisma.StatusHistoryOrderByWithRelationInput;
9
+};
10
+
11
+const StatusHistoryRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllArgs) => {
13
+        return prisma.statusHistory.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                user: {
21
+                    select: {
22
+                        id: true,
23
+                        fullname: true,
24
+                    },
25
+                },
26
+                old_status: true,
27
+                new_status: true,
28
+                note: true,
29
+                createdAt: true,
30
+                updatedAt: true,
31
+            },
32
+        });
33
+    },
34
+
35
+    countAll: async (where: Prisma.StatusHistoryWhereInput) => {
36
+        return prisma.statusHistory.count({ where });
37
+    },
38
+
39
+    create: async (data: Prisma.StatusHistoryCreateInput) => {
40
+        return prisma.statusHistory.create({ data });
41
+    },
42
+};
43
+
44
+export default StatusHistoryRepository;
45
+
46
+// const prisma = require('../../prisma/PrismaClient.js');
47
+
48
+// const StatusHistoryRepository = {
49
+//     findAll: async ({ skip, take, where, orderBy }) => {
50
+//         return prisma.statusHistory.findMany({
51
+//             where,
52
+//             skip,
53
+//             take,
54
+//             orderBy,
55
+//             select: {
56
+//                 id: true,
57
+//                 hospital: {
58
+//                     select: {
59
+//                         id: true,
60
+//                         name: true,
61
+//                         // hospital_code: true,
62
+//                         // type: true,
63
+//                         // ownership: true,
64
+//                         // province: {
65
+//                         //     select: {
66
+//                         //         id: true,
67
+//                         //         name: true
68
+//                         //     }
69
+//                         // },
70
+//                         // city: {
71
+//                         //     select: {
72
+//                         //         id: true,
73
+//                         //         name: true
74
+//                         //     }
75
+//                         // },
76
+//                         // address: true,
77
+//                         // simrs_type: true,
78
+//                         // contact: true,
79
+//                         // image: true,
80
+//                         progress_status: true,
81
+//                         // note: true,
82
+//                         // user: {
83
+//                         //     select: {
84
+//                         //         id: true,
85
+//                         //         username: true
86
+//                         //     }
87
+//                         // }
88
+//                     }
89
+//                 },
90
+//                 user: {
91
+//                     select: {
92
+//                         id: true,
93
+//                         fullname: true,
94
+//                     }
95
+//                 },
96
+//                 // user_id: true,
97
+//                 old_status: true,
98
+//                 new_status: true,
99
+//                 note: true,
100
+//                 createdAt: true,
101
+//                 updatedAt: true,
102
+//             },
103
+//         });
104
+//     },
105
+
106
+//     countAll: async (where) => {
107
+//         return prisma.statusHistory.count({ where });
108
+//     },
109
+
110
+//     create: async (data) => {
111
+//         return prisma.statusHistory.create({ data });
112
+//     },
113
+// };
114
+
115
+// module.exports = StatusHistoryRepository;

+ 182 - 0
src/repository/sales/VendorExperienceRepository.ts

@@ -0,0 +1,182 @@
1
+import { PrismaClient, Prisma } from '@prisma/client';
2
+const prisma = new PrismaClient();
3
+
4
+interface FindAllParams {
5
+    skip?: number;
6
+    take?: number;
7
+    where?: Prisma.VendorExperienceWhereInput;
8
+    orderBy?: Prisma.VendorExperienceOrderByWithRelationInput;
9
+}
10
+
11
+const VendorExperienceRepository = {
12
+    findAll: async ({ skip, take, where, orderBy }: FindAllParams) => {
13
+        return prisma.vendorExperience.findMany({
14
+            where,
15
+            skip,
16
+            take,
17
+            orderBy,
18
+            select: {
19
+                id: true,
20
+                vendor: {
21
+                    select: {
22
+                        id: true,
23
+                        name: true,
24
+                        name_pt: true,
25
+                        strengths: true,
26
+                        weaknesses: true,
27
+                        website: true,
28
+                        created_by: true,
29
+                    },
30
+                },
31
+                status: true,
32
+                simrs_type: true,
33
+                contract_value_min: true,
34
+                contract_value_max: true,
35
+                contract_start_date: true,
36
+                contract_expired_date: true,
37
+                positive_notes: true,
38
+                negative_notes: true,
39
+                createdAt: true,
40
+                updatedAt: true,
41
+            },
42
+        });
43
+    },
44
+
45
+    countAll: async (where?: Prisma.VendorExperienceWhereInput) => {
46
+        return prisma.vendorExperience.count({ where });
47
+    },
48
+
49
+    findById: async (id: string) => {
50
+        return prisma.vendorExperience.findFirst({
51
+            where: {
52
+                id,
53
+                deletedAt: null,
54
+            },
55
+            select: {
56
+                id: true,
57
+                vendor_id: true,
58
+                vendor: {
59
+                    select: {
60
+                        id: true,
61
+                        name: true,
62
+                        name_pt: true,
63
+                        strengths: true,
64
+                        weaknesses: true,
65
+                        website: true,
66
+                        created_by: true,
67
+                    },
68
+                },
69
+                status: true,
70
+                simrs_type: true,
71
+                contract_value_min: true,
72
+                contract_value_max: true,
73
+                contract_start_date: true,
74
+                contract_expired_date: true,
75
+                positive_notes: true,
76
+                negative_notes: true,
77
+                createdAt: true,
78
+                updatedAt: true,
79
+            },
80
+        });
81
+    },
82
+
83
+    create: async (data: Prisma.VendorExperienceCreateInput) => {
84
+        return prisma.vendorExperience.create({ data });
85
+    },
86
+
87
+    update: async (id: string, data: Prisma.VendorExperienceUpdateInput) => {
88
+        return prisma.vendorExperience.update({
89
+            where: { id },
90
+            data,
91
+        });
92
+    },
93
+};
94
+
95
+export default VendorExperienceRepository;
96
+
97
+// const prisma = require('../../prisma/PrismaClient.js');
98
+
99
+// const VendorExperienceRepository = {
100
+//     findAll: async ({ skip, take, where, orderBy }) => {
101
+//         return prisma.vendorExperience.findMany({
102
+//             where,
103
+//             skip,
104
+//             take,
105
+//             orderBy,
106
+//             select: {
107
+//                 id: true,
108
+//                 vendor: {
109
+//                     select: {
110
+//                         id: true,
111
+//                         name: true,
112
+//                         name_pt: true,
113
+//                         strengths: true,
114
+//                         weaknesses: true,
115
+//                         website: true,
116
+//                         created_by: true,
117
+//                     }
118
+//                 },
119
+//                 status: true,
120
+//                 simrs_type: true,
121
+//                 contract_value_min: true,
122
+//                 contract_value_max: true,
123
+//                 contract_start_date: true,
124
+//                 contract_expired_date: true,
125
+//                 positive_notes: true,
126
+//                 negative_notes: true,
127
+//                 createdAt: true,
128
+//                 updatedAt: true,
129
+//             },
130
+//         });
131
+//     },
132
+
133
+//     countAll: async (where) => {
134
+//         return prisma.vendorExperience.count({ where });
135
+//     },
136
+
137
+//     findById: async (id) => {
138
+//         return prisma.vendorExperience.findFirst({
139
+//             where: {
140
+//                 id,
141
+//                 deletedAt: null
142
+//             },
143
+//             select: {
144
+//                 id: true,
145
+//                 vendor: {
146
+//                     select: {
147
+//                         id: true,
148
+//                         name: true,
149
+//                         name_pt: true,
150
+//                         strengths: true,
151
+//                         weaknesses: true,
152
+//                         website: true,
153
+//                         created_by: true,
154
+//                     }
155
+//                 },
156
+//                 status: true,
157
+//                 simrs_type: true,
158
+//                 contract_value_min: true,
159
+//                 contract_value_max: true,
160
+//                 contract_start_date: true,
161
+//                 contract_expired_date: true,
162
+//                 positive_notes: true,
163
+//                 negative_notes: true,
164
+//                 createdAt: true,
165
+//                 updatedAt: true,
166
+//             },
167
+//         });
168
+//     },
169
+
170
+//     create: async (data) => {
171
+//         return prisma.vendorExperience.create({ data });
172
+//     },
173
+
174
+//     update: async (id, data) => {
175
+//         return prisma.vendorExperience.update({
176
+//             where: { id },
177
+//             data
178
+//         });
179
+//     },
180
+// };
181
+
182
+// module.exports = VendorExperienceRepository;

+ 0 - 134
src/repository/sales/VendorHistoryRepository.js

@@ -1,134 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const VendorHistoryRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.vendorHistory.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                // hospital: {
13
-                //     select: {
14
-                //         id: true,
15
-                //         name: true,
16
-                //         hospital_code: true,
17
-                //         type: true,
18
-                //         ownership: true,
19
-                //         province: {
20
-                //             select: {
21
-                //                 id: true,
22
-                //                 name: true
23
-                //             }
24
-                //         },
25
-                //         city: {
26
-                //             select: {
27
-                //                 id: true,
28
-                //                 name: true
29
-                //             }
30
-                //         },
31
-                //         address: true,
32
-                //         simrs_type: true,
33
-                //         contact: true,
34
-                //         image: true,
35
-                //         progress_status: true,
36
-                //         note: true,
37
-                //         created_by: true
38
-                //     }
39
-                // },
40
-                vendor: {
41
-                    select: {
42
-                        id: true,
43
-                        name: true,
44
-                        name_pt: true,
45
-                        strengths: true,
46
-                        weaknesses: true,
47
-                        website: true,
48
-                        created_by: true,
49
-                    }
50
-                },
51
-                vendor_impression: true,
52
-                status: true,
53
-                contract_date: true,
54
-                contract_expired_date: true,
55
-                createdAt: true,
56
-                updatedAt: true,
57
-            },
58
-        });
59
-    },
60
-
61
-    countAll: async (where) => {
62
-        return prisma.vendorHistory.count({ where });
63
-    },
64
-
65
-    findById: async (id) => {
66
-        return prisma.vendorHistory.findFirst({
67
-            where: {
68
-                id,
69
-                deletedAt: null
70
-            },
71
-            select: {
72
-                id: true,
73
-                // hospital: {
74
-                //     select: {
75
-                //         id: true,
76
-                //         name: true,
77
-                //         hospital_code: true,
78
-                //         type: true,
79
-                //         ownership: true,
80
-                //         province: {
81
-                //             select: {
82
-                //                 id: true,
83
-                //                 name: true
84
-                //             }
85
-                //         },
86
-                //         city: {
87
-                //             select: {
88
-                //                 id: true,
89
-                //                 name: true
90
-                //             }
91
-                //         },
92
-                //         address: true,
93
-                //         simrs_type: true,
94
-                //         contact: true,
95
-                //         image: true,
96
-                //         progress_status: true,
97
-                //         note: true,
98
-                //         created_by: true
99
-                //     }
100
-                // },
101
-                vendor: {
102
-                    select: {
103
-                        id: true,
104
-                        name: true,
105
-                        name_pt: true,
106
-                        strengths: true,
107
-                        weaknesses: true,
108
-                        website: true,
109
-                        created_by: true,
110
-                    }
111
-                },
112
-                vendor_impression: true,
113
-                status: true,
114
-                contract_date: true,
115
-                contract_expired_date: true,
116
-                createdAt: true,
117
-                updatedAt: true,
118
-            },
119
-        });
120
-    },
121
-
122
-    create: async (data) => {
123
-        return prisma.vendorHistory.create({ data });
124
-    },
125
-
126
-    update: async (id, data) => {
127
-        return prisma.vendorHistory.update({
128
-            where: { id },
129
-            data
130
-        });
131
-    },
132
-};
133
-
134
-module.exports = VendorHistoryRepository;

+ 0 - 117
src/repository/sales/VendorRepository.js

@@ -1,117 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-const { formatDateOnly } = require('../../utils/FormatDate.js');
3
-
4
-const VendorRepository = {
5
-    findAll: async ({ skip, take, where, orderBy }) => {
6
-        const rawVendors = await prisma.vendor.findMany({
7
-            where,
8
-            skip,
9
-            take,
10
-            orderBy,
11
-            select: {
12
-                id: true,
13
-                name: true,
14
-                name_pt: true,
15
-                strengths: true,
16
-                weaknesses: true,
17
-                website: true,
18
-                user: {
19
-                    select: {
20
-                        id: true,
21
-                        username: true,
22
-                        email: true,
23
-                        firstname: true,
24
-                        lastname: true,
25
-                    }
26
-                },
27
-                createdAt: true,
28
-                updatedAt: true,
29
-                vendor_histories: {
30
-                    where: {
31
-                        deletedAt: null,
32
-                        status: 'active',
33
-                        hospital: {
34
-                            deletedAt: null
35
-                        }
36
-                    },
37
-                    select: {
38
-                        vendor_impression: true,
39
-                        contract_date: true,
40
-                        contract_expired_date: true,
41
-                        hospital: {
42
-                            select: {
43
-                                id: true,
44
-                                name: true,
45
-                                hospital_code: true,
46
-                                address: true,
47
-                                city: {
48
-                                    select: { name: true }
49
-                                },
50
-                                province: {
51
-                                    select: { name: true }
52
-                                }
53
-                            }
54
-                        }
55
-                    }
56
-                }
57
-            },
58
-        });
59
-
60
-        // Format tanggal di dalam vendor_histories
61
-        const vendors = rawVendors.map(vendor => ({
62
-            ...vendor,
63
-            vendor_histories: vendor.vendor_histories.map(vh => ({
64
-                ...vh,
65
-                contract_date: formatDateOnly(vh.contract_date),
66
-                contract_expired_date: formatDateOnly(vh.contract_expired_date),
67
-            }))
68
-        }));
69
-
70
-        return vendors;
71
-    },
72
-
73
-    countAll: async (where) => {
74
-        return prisma.vendor.count({ where });
75
-    }
76
-
77
-    // findById: async (id) => {
78
-    //     return prisma.vendor.findFirst({
79
-    //         where: {
80
-    //             id,
81
-    //             deletedAt: null
82
-    //         },
83
-    //         select: {
84
-    //             id: true,
85
-    //             name: true,
86
-    //             name_pt: true,
87
-    //             strengths: true,
88
-    //             weaknesses: true,
89
-    //             website: true,
90
-    //             user: {
91
-    //                 select: {
92
-    //                     id: true,
93
-    //                     username: true,
94
-    //                     email: true,
95
-    //                     firstname: true,
96
-    //                     lastname: true,
97
-    //                 }
98
-    //             },
99
-    //             createdAt: true,
100
-    //             updatedAt: true,
101
-    //         },
102
-    //     });
103
-    // },
104
-
105
-    // create: async (data) => {
106
-    //     return prisma.vendor.create({ data });
107
-    // },
108
-
109
-    // update: async (id, data) => {
110
-    //     return prisma.vendor.update({
111
-    //         where: { id },
112
-    //         data
113
-    //     });
114
-    // },
115
-};
116
-
117
-module.exports = VendorRepository;

+ 0 - 219
src/repository/superadmin/AdminRepository.js

@@ -1,219 +0,0 @@
1
-const axios = require('axios');
2
-const qs = require('qs');
3
-const {
4
-    KEYCLOAK_REALM,
5
-    KEYCLOAK_ADMIN_URL,
6
-    CLIENT_ID,
7
-    CLIENT_SECRET
8
-} = require('../../../config/keycloak.js');
9
-const HttpException = require('../../utils/HttpException.js');
10
-const bcrypt = require('bcrypt');
11
-const prisma = require('../../prisma/PrismaClient.js');
12
-
13
-const getAdminToken = async () => {
14
-    const tokenParams = qs.stringify({
15
-        grant_type: 'client_credentials',
16
-        client_id: CLIENT_ID,
17
-        client_secret: CLIENT_SECRET
18
-    });
19
-
20
-    const { data } = await axios.post(
21
-        `${KEYCLOAK_ADMIN_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`,
22
-        tokenParams,
23
-        {
24
-            headers: {
25
-                'Content-Type': 'application/x-www-form-urlencoded'
26
-            }
27
-        }
28
-    );
29
-
30
-    return data.access_token;
31
-};
32
-
33
-const KeycloakRepository = {
34
-    createUser: async (userData) => {
35
-        const token = await getAdminToken();
36
-
37
-        // Cek apakah username sudah terpakai
38
-        const { data: usersByUsername } = await axios.get(
39
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?username=${encodeURIComponent(userData.username)}`,
40
-            { headers: { Authorization: `Bearer ${token}` } }
41
-        );
42
-
43
-        if (usersByUsername.length > 0) {
44
-            throw new HttpException('Username already exists in Keycloak', 409);
45
-        }
46
-
47
-        // Cek apakah email sudah terpakai
48
-        const { data: usersByEmail } = await axios.get(
49
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users?email=${encodeURIComponent(userData.email)}`,
50
-            { headers: { Authorization: `Bearer ${token}` } }
51
-        );
52
-
53
-        if (usersByEmail.length > 0) {
54
-            throw new HttpException('Email already exists in Keycloak', 409);
55
-        }
56
-
57
-        const response = await axios.post(
58
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users`,
59
-            {
60
-                username: userData.username,
61
-                email: userData.email,
62
-                firstName: userData.firstname,
63
-                lastName: userData.lastname,
64
-                enabled: true,
65
-                credentials: [{
66
-                    type: "password",
67
-                    value: userData.password,
68
-                    temporary: false
69
-                }]
70
-            },
71
-            { headers: { Authorization: `Bearer ${token}` } }
72
-        );
73
-
74
-        return response.headers.location.split('/').pop();
75
-    },
76
-
77
-    assignAdminRole: async (userId) => {
78
-        const token = await getAdminToken();
79
-
80
-        // Get role sales
81
-        const { data: roles } = await axios.get(
82
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/roles`,
83
-            { headers: { Authorization: `Bearer ${token}` } }
84
-        );
85
-
86
-        const adminRole = roles.find(role => role.name === 'admin');
87
-        if (!adminRole) throw new HttpException('Admin role not found in Keycloak', 500);
88
-
89
-        // Assign role to user
90
-        await axios.post(
91
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}/role-mappings/realm`,
92
-            [adminRole],
93
-            { headers: { Authorization: `Bearer ${token}` } }
94
-        );
95
-    },
96
-
97
-    updateUser: async (userId, updatedData) => {
98
-        const token = await getAdminToken();
99
-
100
-        await axios.put(
101
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
102
-            {
103
-                firstName: updatedData.firstname,
104
-                lastName: updatedData.lastname,
105
-                email: updatedData.email,
106
-                credentials: updatedData.password ? [{
107
-                    type: 'password',
108
-                    value: updatedData.password,
109
-                    temporary: false
110
-                }] : undefined
111
-            },
112
-            { headers: { Authorization: `Bearer ${token}` } }
113
-        );
114
-    },
115
-
116
-    deleteUser: async (userId) => {
117
-        const token = await getAdminToken();
118
-
119
-        await axios.delete(
120
-            `${KEYCLOAK_ADMIN_URL}/admin/realms/${KEYCLOAK_REALM}/users/${userId}`,
121
-            { headers: { Authorization: `Bearer ${token}` } }
122
-        );
123
-    }
124
-};
125
-
126
-const AdminRepository = {
127
-    createUser: async (userId, userData) => {
128
-        const hashedPassword = await bcrypt.hash(userData.password, 10);
129
-
130
-        return prisma.user.create({
131
-            data: {
132
-                id: userId,
133
-                username: userData.username,
134
-                email: userData.email,
135
-                firstname: userData.firstname,
136
-                lastname: userData.lastname,
137
-                password: hashedPassword,
138
-                role: 'admin'
139
-            }
140
-        });
141
-    },
142
-
143
-    findAll: async ({ skip, take, where, orderBy }) => {
144
-        return prisma.user.findMany({
145
-            where: {
146
-                ...where,
147
-                role: 'admin'
148
-            },
149
-            skip,
150
-            take,
151
-            orderBy,
152
-            select: {
153
-                id: true,
154
-                username: true,
155
-                email: true,
156
-                firstname: true,
157
-                lastname: true,
158
-                role: true,
159
-                createdAt: true,
160
-                updatedAt: true,
161
-            },
162
-        });
163
-    },
164
-
165
-    countAll: async (where) => {
166
-        return prisma.user.count({
167
-            where: {
168
-                ...where,
169
-                role: 'admin'
170
-            }
171
-        });
172
-    },
173
-
174
-    findById: async (id) => {
175
-        return prisma.user.findFirst({
176
-            where: {
177
-                id,
178
-                deletedAt: null
179
-            },
180
-            select: {
181
-                id: true,
182
-                username: true,
183
-                email: true,
184
-                firstname: true,
185
-                lastname: true,
186
-                createdAt: true,
187
-                updatedAt: true,
188
-            }
189
-        });
190
-    },
191
-
192
-    updateUser: async (id, updatedData) => {
193
-        const updatePayload = {
194
-            email: updatedData.email,
195
-            firstname: updatedData.firstname,
196
-            lastname: updatedData.lastname
197
-        };
198
-
199
-        if (updatedData.password) {
200
-            updatePayload.password = await bcrypt.hash(updatedData.password, 10);
201
-        }
202
-
203
-        return prisma.user.update({
204
-            where: { id },
205
-            data: updatePayload
206
-        });
207
-    },
208
-
209
-    deleteUser: async (id) => {
210
-        return prisma.user.update({
211
-            where: { id },
212
-            data: {
213
-                deletedAt: new Date()
214
-            }
215
-        });
216
-    }
217
-};
218
-
219
-module.exports = { KeycloakRepository, AdminRepository };

+ 0 - 24
src/repository/superadmin/LogRepository.js

@@ -1,24 +0,0 @@
1
-const prisma = require('../../prisma/PrismaClient.js');
2
-
3
-const LogRepository = {
4
-    findAll: async ({ skip, take, where, orderBy }) => {
5
-        return prisma.activityLog.findMany({
6
-            where,
7
-            skip,
8
-            take,
9
-            orderBy,
10
-            select: {
11
-                id: true,
12
-                username: true,
13
-                action: true,
14
-                createdAt: true,
15
-            },
16
-        });
17
-    },
18
-
19
-    countAll: async (where) => {
20
-        return prisma.activityLog.count({ where });
21
-    },
22
-}
23
-
24
-module.exports = LogRepository;

+ 3 - 21
src/resources/admin/city/CityCollection.ts

@@ -1,33 +1,15 @@
1 1
 import { Request, Response } from 'express';
2 2
 import { ListResponse } from '../../../utils/ListResponse';
3 3
 import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { CityDTO } from '../../../types/admin/city/CityDTO';
4 5
 
5
-interface CityItem {
6
-    createdAt: Date;
7
-    updatedAt: Date;
8
-    [key: string]: any;
9
-}
10
-
11
-interface CityFormattedItem extends Omit<CityItem, 'createdAt' | 'updatedAt'> {
12
-    createdAt: string | null;
13
-    updatedAt: string | null;
14
-}
15
-
16
-const formatItem = (item: CityItem): CityFormattedItem => ({
6
+const formatItem = (item: CityDTO) => ({
17 7
     ...item,
18 8
     createdAt: formatISOWithoutTimezone(item.createdAt),
19 9
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
20 10
 });
21 11
 
22
-export const CityCollection = (
23
-    req: Request,
24
-    res: Response,
25
-    data: CityItem[] = [],
26
-    total: number | null = null,
27
-    page: number = 1,
28
-    limit: number = 10,
29
-    message: string = 'Success'
30
-): Response => {
12
+export const CityCollection = (req: Request, res: Response, data: CityDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
31 13
     const formattedData = data.map(formatItem);
32 14
 
33 15
     if (typeof total !== 'number') {

+ 3 - 17
src/resources/admin/city/CityResource.ts

@@ -1,28 +1,14 @@
1 1
 import { Response } from 'express';
2 2
 import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
3
+import { CityDTO } from '../../../types/admin/city/CityDTO';
3 4
 
4
-interface CityItem {
5
-    [key: string]: any;
6
-    createdAt: Date;
7
-    updatedAt: Date;
8
-}
9
-
10
-interface FormattedCityItem extends Omit<CityItem, 'createdAt' | 'updatedAt'> {
11
-    createdAt: string | null;
12
-    updatedAt: string | null;
13
-}
14
-
15
-const formatItem = (item: CityItem): FormattedCityItem => ({
5
+const formatItem = (item: CityDTO) => ({
16 6
     ...item,
17 7
     createdAt: formatISOWithoutTimezone(item.createdAt),
18 8
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
19 9
 });
20 10
 
21
-export const CityResource = (
22
-    res: Response,
23
-    data: CityItem,
24
-    message: string = 'Success'
25
-): Response => {
11
+export const CityResource = (res: Response, data: CityDTO, message: string = 'Success'): Response => {
26 12
     const formattedData = formatItem(data);
27 13
 
28 14
     return res.status(200).json({

+ 0 - 24
src/resources/admin/executives_history/ExecutivesHistoriCollection.js

@@ -1,24 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse");
2
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
3
-
4
-const formatItem = (item) => ({
5
-    ...item,
6
-    start_term: formatDateOnly(item.start_term),
7
-    end_term: formatDateOnly(item.end_term),
8
-    createdAt: formatISOWithoutTimezone(item.createdAt),
9
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
-});
11
-
12
-exports.ExecutivesHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
13
-    const formattedData = data.map(formatItem);
14
-
15
-    if (typeof total !== 'number') {
16
-        return res.status(200).json({
17
-            success: true,
18
-            message,
19
-            data: Array.isArray(formattedData)
20
-        });
21
-    }
22
-
23
-    return ListResponse({ req, res, data: formattedData, total, page, limit, message });
24
-};

+ 60 - 0
src/resources/admin/executives_history/ExecutivesHistoriCollection.ts

@@ -0,0 +1,60 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone, formatDateOnly } from '../../../utils/FormatDate';
4
+import { ExecutiveHistoryDTO } from '../../../types/admin/executives_history/ExecutivesHistoryDTO';
5
+
6
+const formatItem = (item: ExecutiveHistoryDTO): ExecutiveHistoryDTO => ({
7
+    ...item,
8
+    start_term: formatDateOnly(item.start_term),
9
+    end_term: formatDateOnly(item.end_term),
10
+    createdAt: formatISOWithoutTimezone(item.createdAt),
11
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
12
+});
13
+
14
+export const ExecutivesHistoriCollection = (
15
+    req: Request,
16
+    res: Response,
17
+    data: ExecutiveHistoryDTO[] = [],
18
+    total: number | null = null,
19
+    page = 1,
20
+    limit = 10,
21
+    message = 'Success'
22
+): Response => {
23
+    const formattedData = data.map(formatItem);
24
+
25
+    if (typeof total !== 'number') {
26
+        return res.status(200).json({
27
+            success: true,
28
+            message,
29
+            data: Array.isArray(formattedData)
30
+        });
31
+    }
32
+
33
+    return ListResponse({ req, res, data: formattedData, total, page, limit, message });
34
+};
35
+
36
+
37
+// const { ListResponse } = require("../../../utils/ListResponse");
38
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
39
+
40
+// const formatItem = (item) => ({
41
+//     ...item,
42
+//     start_term: formatDateOnly(item.start_term),
43
+//     end_term: formatDateOnly(item.end_term),
44
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
45
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
46
+// });
47
+
48
+// exports.ExecutivesHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
49
+//     const formattedData = data.map(formatItem);
50
+
51
+//     if (typeof total !== 'number') {
52
+//         return res.status(200).json({
53
+//             success: true,
54
+//             message,
55
+//             data: Array.isArray(formattedData)
56
+//         });
57
+//     }
58
+
59
+//     return ListResponse({ req, res, data: formattedData, total, page, limit, message });
60
+// };

+ 0 - 19
src/resources/admin/executives_history/ExecutivesHistoriResource.js

@@ -1,19 +0,0 @@
1
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
2
-
3
-const formatItem = (item) => ({
4
-    ...item,
5
-    start_term: formatDateOnly(item.start_term),
6
-    end_term: formatDateOnly(item.end_term),
7
-    createdAt: formatISOWithoutTimezone(item.createdAt),
8
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
9
-});
10
-
11
-exports.ExecutivesHistoriResource = (res, data, message = 'Success') => {
12
-    const formattedData = formatItem(data);
13
-
14
-    return res.status(200).json({
15
-        success: true,
16
-        message,
17
-        data: formattedData
18
-    });
19
-};

+ 45 - 0
src/resources/admin/executives_history/ExecutivesHistoriResource.ts

@@ -0,0 +1,45 @@
1
+import { Response } from 'express';
2
+import { formatISOWithoutTimezone, formatDateOnly } from '../../../utils/FormatDate';
3
+import { ExecutiveHistoryDTO } from '../../../types/admin/executives_history/ExecutivesHistoryDTO';
4
+
5
+const formatItem = (item: ExecutiveHistoryDTO): ExecutiveHistoryDTO => ({
6
+    ...item,
7
+    start_term: formatDateOnly(item.start_term),
8
+    end_term: formatDateOnly(item.end_term),
9
+    createdAt: formatISOWithoutTimezone(item.createdAt),
10
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
11
+});
12
+
13
+export const ExecutivesHistoriResource = (
14
+    res: Response,
15
+    data: ExecutiveHistoryDTO,
16
+    message = 'Success'
17
+): Response => {
18
+    const formattedData = formatItem(data);
19
+
20
+    return res.status(200).json({
21
+        success: true,
22
+        message,
23
+        data: formattedData
24
+    });
25
+};
26
+
27
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
28
+
29
+// const formatItem = (item) => ({
30
+//     ...item,
31
+//     start_term: formatDateOnly(item.start_term),
32
+//     end_term: formatDateOnly(item.end_term),
33
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
34
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
35
+// });
36
+
37
+// exports.ExecutivesHistoriResource = (res, data, message = 'Success') => {
38
+//     const formattedData = formatItem(data);
39
+
40
+//     return res.status(200).json({
41
+//         success: true,
42
+//         message,
43
+//         data: formattedData
44
+//     });
45
+// };

+ 0 - 27
src/resources/admin/hospital/HospitalCollection.js

@@ -1,27 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse");
2
-const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
3
-const { getUserNameById } = require("../../../utils/CheckUserKeycloak.js");
4
-
5
-// Fungsi transform per item
6
-const transformHospitalList = async (data = []) => {
7
-    return Promise.all(data.map(async ({ created_by, ...rest }) => {
8
-        const name = await getUserNameById(created_by);
9
-
10
-        return {
11
-            ...rest,
12
-            user: {
13
-                id: created_by,
14
-                name: name
15
-            },
16
-            createdAt: formatISOWithoutTimezone(rest.createdAt),
17
-            updatedAt: formatISOWithoutTimezone(rest.updatedAt)
18
-        };
19
-    }));
20
-};
21
-
22
-// Collection yang async
23
-exports.HospitalCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
24
-    const formatted = await transformHospitalList(data);
25
-
26
-    return ListResponse({ req, res, data: formatted, total, page, limit, message });
27
-};

+ 128 - 0
src/resources/admin/hospital/HospitalCollection.ts

@@ -0,0 +1,128 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { HospitalDTO } from '../../../types/admin/hospital/HospitalDTO';
5
+
6
+const formatItem = (item: HospitalDTO) => ({
7
+    ...item,
8
+    createdAt: formatISOWithoutTimezone(item.createdAt),
9
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
+});
11
+
12
+export const HospitalCollection = (req: Request, res: Response, data: HospitalDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
13
+    const formattedData = data.map(formatItem);
14
+
15
+    if (typeof total !== 'number') {
16
+        return res.status(200).json({
17
+            success: true,
18
+            message,
19
+            data: Array.isArray(formattedData),
20
+        });
21
+    }
22
+
23
+    return ListResponse({
24
+        req,
25
+        res,
26
+        data: formattedData,
27
+        total,
28
+        page,
29
+        limit,
30
+        message,
31
+    });
32
+};
33
+
34
+
35
+// ==============================================
36
+
37
+// import { Request, Response } from "express";
38
+// import { ListResponse } from "../../../utils/ListResponse";
39
+// import { formatISOWithoutTimezone } from "../../../utils/FormatDate";
40
+// import { getUserNameById } from "../../../utils/CheckUserKeycloak";
41
+
42
+// // Tipe untuk item rumah sakit
43
+// interface HospitalItem {
44
+//     id: string;
45
+//     name: string;
46
+//     created_by?: string;
47
+//     createdAt: Date | string;
48
+//     updatedAt: Date | string;
49
+//     [key: string]: any;
50
+// }
51
+
52
+// // Fungsi transform per item
53
+// const transformHospitalList = async (data: HospitalItem[] = []): Promise<any[]> => {
54
+//     return Promise.all(
55
+//         data.map(async ({ created_by, ...rest }) => {
56
+//             // const name = await getUserNameById(created_by);
57
+
58
+//             return {
59
+//                 ...rest,
60
+//                 // user: {
61
+//                 //   id: created_by,
62
+//                 //   name: name,
63
+//                 // },
64
+//                 createdAt: formatISOWithoutTimezone(rest.createdAt),
65
+//                 updatedAt: formatISOWithoutTimezone(rest.updatedAt),
66
+//             };
67
+//         })
68
+//     );
69
+// };
70
+
71
+// // Collection yang async
72
+// export const HospitalCollection = async ({
73
+//     req,
74
+//     res,
75
+//     data = [],
76
+//     total = 0,
77
+//     page = 1,
78
+//     limit = 10,
79
+//     message = "Success",
80
+// }: {
81
+//     req: Request;
82
+//     res: Response;
83
+//     data: HospitalItem[];
84
+//     total: number;
85
+//     page: number;
86
+//     limit: number;
87
+//     message?: string;
88
+// }) => {
89
+//     const formatted = await transformHospitalList(data);
90
+
91
+//     return ListResponse({
92
+//         req,
93
+//         res,
94
+//         data: formatted,
95
+//         total,
96
+//         page,
97
+//         limit,
98
+//         message,
99
+//     });
100
+// };
101
+
102
+// const { ListResponse } = require("../../../utils/ListResponse");
103
+// const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
104
+// const { getUserNameById } = require("../../../utils/CheckUserKeycloak.js");
105
+
106
+// // Fungsi transform per item
107
+// const transformHospitalList = async (data = []) => {
108
+//     return Promise.all(data.map(async ({ created_by, ...rest }) => {
109
+//         // const name = await getUserNameById(created_by);
110
+
111
+//         return {
112
+//             ...rest,
113
+//             // user: {
114
+//             //     id: created_by,
115
+//             //     name: name
116
+//             // },
117
+//             createdAt: formatISOWithoutTimezone(rest.createdAt),
118
+//             updatedAt: formatISOWithoutTimezone(rest.updatedAt)
119
+//         };
120
+//     }));
121
+// };
122
+
123
+// // Collection yang async
124
+// exports.HospitalCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
125
+//     const formatted = await transformHospitalList(data);
126
+
127
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
128
+// };

+ 0 - 17
src/resources/admin/hospital/HospitalResource.js

@@ -1,17 +0,0 @@
1
-const { formatISOWithoutTimezone } = require("../../../utils/FormatDate");
2
-
3
-const formatItem = (item) => ({
4
-    ...item,
5
-    createdAt: formatISOWithoutTimezone(item.createdAt),
6
-    updatedAt: formatISOWithoutTimezone(item.updatedAt)
7
-});
8
-
9
-exports.HospitalResource = (res, data, message = 'Success') => {
10
-    const formattedData = formatItem(data);
11
-
12
-    return res.status(200).json({
13
-        success: true,
14
-        message,
15
-        data: formattedData
16
-    });
17
-};

+ 65 - 0
src/resources/admin/hospital/HospitalResource.ts

@@ -0,0 +1,65 @@
1
+import { Response } from 'express';
2
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
3
+import { HospitalDTO } from '../../../types/admin/hospital/HospitalDTO';
4
+
5
+const formatItem = (item: HospitalDTO) => ({
6
+    ...item,
7
+    createdAt: formatISOWithoutTimezone(item.createdAt),
8
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
9
+});
10
+
11
+export const HospitalResource = (res: Response, data: HospitalDTO, message: string = 'Success'): Response => {
12
+    const formattedData = formatItem(data);
13
+
14
+    return res.status(200).json({
15
+        success: true,
16
+        message,
17
+        data: formattedData,
18
+    });
19
+};
20
+// ==================================================
21
+
22
+// import { Response } from 'express';
23
+// import { formatISOWithoutTimezone } from "../../../utils/FormatDate";
24
+
25
+// interface HospitalItem {
26
+//     createdAt: string | Date;
27
+//     updatedAt: string | Date;
28
+//     [key: string]: any;
29
+// }
30
+
31
+// export const HospitalResource = (
32
+//     res: Response,
33
+//     data: HospitalItem,
34
+//     message: string = 'Success'
35
+// ) => {
36
+//     const formattedData = {
37
+//         ...data,
38
+//         createdAt: formatISOWithoutTimezone(data.createdAt),
39
+//         updatedAt: formatISOWithoutTimezone(data.updatedAt)
40
+//     };
41
+
42
+//     return res.status(200).json({
43
+//         success: true,
44
+//         message,
45
+//         data: formattedData
46
+//     });
47
+// };
48
+
49
+// const { formatISOWithoutTimezone } = require("../../../utils/FormatDate");
50
+
51
+// const formatItem = (item) => ({
52
+//     ...item,
53
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
54
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt)
55
+// });
56
+
57
+// exports.HospitalResource = (res, data, message = 'Success') => {
58
+//     const formattedData = formatItem(data);
59
+
60
+//     return res.status(200).json({
61
+//         success: true,
62
+//         message,
63
+//         data: formattedData
64
+//     });
65
+// };

+ 3 - 18
src/resources/admin/province/ProvinceCollection.ts

@@ -1,30 +1,15 @@
1 1
 import { Request, Response } from 'express';
2 2
 import { ListResponse } from '../../../utils/ListResponse';
3 3
 import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { ProvinceDTO } from '../../../types/admin/province/ProvinceDTO';
4 5
 
5
-interface Province {
6
-    id: string;
7
-    name: string;
8
-    createdAt: Date;
9
-    updatedAt: Date;
10
-    [key: string]: any; // properti tambahan
11
-}
12
-
13
-const formatItem = (item: Province) => ({
6
+const formatItem = (item: ProvinceDTO) => ({
14 7
     ...item,
15 8
     createdAt: formatISOWithoutTimezone(item.createdAt),
16 9
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
17 10
 });
18 11
 
19
-export const ProvinceCollection = (
20
-    req: Request,
21
-    res: Response,
22
-    data: Province[] = [],
23
-    total: number | null = null,
24
-    page: number = 1,
25
-    limit: number = 10,
26
-    message: string = 'Success'
27
-) => {
12
+export const ProvinceCollection = (req: Request, res: Response, data: ProvinceDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success') => {
28 13
     const formattedData = data.map(formatItem);
29 14
 
30 15
     if (typeof total !== 'number') {

+ 3 - 14
src/resources/admin/province/ProvinceResource.ts

@@ -1,25 +1,14 @@
1 1
 import { Response } from 'express';
2 2
 import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
3
+import { ProvinceDTO } from '../../../types/admin/province/ProvinceDTO';
3 4
 
4
-interface Province {
5
-    id: string;
6
-    name: string;
7
-    createdAt: Date;
8
-    updatedAt: Date;
9
-    [key: string]: any; // untuk menangani properti tambahan
10
-}
11
-
12
-const formatItem = (item: Province) => ({
5
+const formatItem = (item: ProvinceDTO) => ({
13 6
     ...item,
14 7
     createdAt: formatISOWithoutTimezone(item.createdAt),
15 8
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
16 9
 });
17 10
 
18
-export const ProvinceResource = (
19
-    res: Response,
20
-    data: Province,
21
-    message: string = 'Success'
22
-) => {
11
+export const ProvinceResource = (res: Response, data: ProvinceDTO, message: string = 'Success') => {
23 12
     const formattedData = formatItem(data);
24 13
 
25 14
     return res.status(200).json({

+ 0 - 27
src/resources/admin/status_history/StatusHistoryCollection.js

@@ -1,27 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse");
2
-const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
3
-const { getUserNameById } = require("../../../utils/CheckUserKeycloak.js");
4
-
5
-const transformStatusHistoryList = async (data = []) => {
6
-    return Promise.all(data.map(async ({ user_id, ...rest }) => {
7
-        const name = await getUserNameById(user_id);
8
-
9
-        return {
10
-            ...rest,
11
-            user: {
12
-                id: user_id,
13
-                name: name
14
-            },
15
-            note: rest.note?.trim() === '' ? null : rest.note,
16
-            createdAt: formatISOWithoutTimezone(rest.createdAt),
17
-            updatedAt: formatISOWithoutTimezone(rest.updatedAt)
18
-        };
19
-    }));
20
-};
21
-
22
-// Collection yang async
23
-exports.StatusHistoryCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
24
-    const formatted = await transformStatusHistoryList(data);
25
-
26
-    return ListResponse({ req, res, data: formatted, total, page, limit, message });
27
-};

+ 137 - 0
src/resources/admin/status_history/StatusHistoryCollection.ts

@@ -0,0 +1,137 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { StatusHistoryDTO } from '../../../types/admin/status_history/StatusHistoryDTO';
5
+
6
+const formatItem = (item: StatusHistoryDTO) => ({
7
+    ...item,
8
+    createdAt: formatISOWithoutTimezone(item.createdAt),
9
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
+});
11
+
12
+export const StatusHistoryCollection = (req: Request, res: Response, data: StatusHistoryDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
13
+    const formattedData = data.map(formatItem);
14
+
15
+    if (typeof total !== 'number') {
16
+        return res.status(200).json({
17
+            success: true,
18
+            message,
19
+            data: Array.isArray(formattedData),
20
+        });
21
+    }
22
+
23
+    return ListResponse({
24
+        req,
25
+        res,
26
+        data: formattedData,
27
+        total,
28
+        page,
29
+        limit,
30
+        message,
31
+    });
32
+};
33
+
34
+// import { ListResponse } from "../../../utils/ListResponse";
35
+// import { formatISOWithoutTimezone } from "../../../utils/FormatDate";
36
+// import { getUserNameById } from "../../../utils/CheckUserKeycloak";
37
+
38
+// // interface StatusHistory {
39
+// //     id: string;
40
+// //     hospital_id: string;
41
+// //     user_id: string;
42
+// //     old_status: 'cari_data' | 'dihubungi' | 'negosiasi' | 'follow_up' | 'mou' | 'onboarded' | 'tidak_berminat';
43
+// //     new_status: 'cari_data' | 'dihubungi' | 'negosiasi' | 'follow_up' | 'mou' | 'onboarded' | 'tidak_berminat';
44
+// //     note?: string | null;
45
+// //     createdAt: string | Date | null;
46
+// //     updatedAt: string | Date | null;
47
+// // }
48
+
49
+// interface StatusHistoryWithRelations {
50
+//     id: string;
51
+//     old_status: string;
52
+//     new_status: string;
53
+//     note: string | null;
54
+//     createdAt: Date | string | null;
55
+//     updatedAt: Date | string | null;
56
+//     hospital: {
57
+//         id: string;
58
+//         name: string;
59
+//         progress_status: string;
60
+//     };
61
+//     user: {
62
+//         id: string;
63
+//         fullname: string;
64
+//     };
65
+// }
66
+
67
+
68
+// const transformStatusHistoryList = async (data: StatusHistoryWithRelations[] = []): Promise<StatusHistoryWithRelations[]> => {
69
+//     return Promise.all(
70
+//         data.map(async (rest): Promise<StatusHistoryWithRelations> => {
71
+//             // const name = await getUserNameById(rest.user_id);
72
+
73
+//             return {
74
+//                 ...rest,
75
+//                 // user: {
76
+//                 //   id: rest.user_id,
77
+//                 //   name,
78
+//                 // },
79
+//                 note: rest.note?.trim() === '' ? null : rest.note ?? null,
80
+//                 createdAt: formatISOWithoutTimezone(rest.createdAt),
81
+//                 updatedAt: formatISOWithoutTimezone(rest.updatedAt),
82
+//             };
83
+//         })
84
+//     );
85
+// };
86
+
87
+// interface StatusHistoryCollectionParams {
88
+//     req: any;
89
+//     res: any;
90
+//     data?: StatusHistoryWithRelations[];
91
+//     total?: number;
92
+//     page?: number;
93
+//     limit?: number;
94
+//     message?: string;
95
+// }
96
+
97
+// export const StatusHistoryCollection = async ({
98
+//     req,
99
+//     res,
100
+//     data = [],
101
+//     total = 0,
102
+//     page = 1,
103
+//     limit = 10,
104
+//     message = 'Success',
105
+// }: StatusHistoryCollectionParams) => {
106
+//     const formatted = await transformStatusHistoryList(data);
107
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
108
+// };
109
+
110
+
111
+// const { ListResponse } = require("../../../utils/ListResponse");
112
+// const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
113
+// const { getUserNameById } = require("../../../utils/CheckUserKeycloak.js");
114
+
115
+// const transformStatusHistoryList = async (data = []) => {
116
+//     return Promise.all(data.map(async ({ ...rest }) => {
117
+//         // const name = await getUserNameById(user_id);
118
+
119
+//         return {
120
+//             ...rest,
121
+//             // user: {
122
+//             //     id: user_id,
123
+//             //     name: name
124
+//             // },
125
+//             note: rest.note?.trim() === '' ? null : rest.note,
126
+//             createdAt: formatISOWithoutTimezone(rest.createdAt),
127
+//             updatedAt: formatISOWithoutTimezone(rest.updatedAt)
128
+//         };
129
+//     }));
130
+// };
131
+
132
+// // Collection yang async
133
+// exports.StatusHistoryCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
134
+//     const formatted = await transformStatusHistoryList(data);
135
+
136
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
137
+// };

+ 0 - 26
src/resources/admin/vendor/VendorCollection.js

@@ -1,26 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse");
2
-const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
3
-const { getUserNameById } = require("../../../utils/CheckUserKeycloak");
4
-
5
-const transformVendorList = async (data = []) => {
6
-    return Promise.all(data.map(async ({ created_by, ...rest }) => {
7
-        const name = await getUserNameById(created_by);
8
-
9
-        return {
10
-            ...rest,
11
-            user: {
12
-                id: created_by,
13
-                name: name
14
-            },
15
-            createdAt: formatISOWithoutTimezone(rest.createdAt),
16
-            updatedAt: formatISOWithoutTimezone(rest.updatedAt)
17
-        };
18
-    }));
19
-};
20
-
21
-// Collection yang async
22
-exports.VendorCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
23
-    const formatted = await transformVendorList(data);
24
-
25
-    return ListResponse({ req, res, data: formatted, total, page, limit, message });
26
-};

+ 112 - 0
src/resources/admin/vendor/VendorCollection.ts

@@ -0,0 +1,112 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { VendorDTO } from '../../../types/admin/vendor/VendorDTO';
5
+
6
+const formatItem = (item: VendorDTO) => ({
7
+    ...item,
8
+    createdAt: formatISOWithoutTimezone(item.createdAt),
9
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
+});
11
+
12
+export const VendorCollection = (req: Request, res: Response, data: VendorDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
13
+    const formattedData = data.map(formatItem);
14
+
15
+    if (typeof total !== 'number') {
16
+        return res.status(200).json({
17
+            success: true,
18
+            message,
19
+            data: Array.isArray(formattedData),
20
+        });
21
+    }
22
+
23
+    return ListResponse({
24
+        req,
25
+        res,
26
+        data: formattedData,
27
+        total,
28
+        page,
29
+        limit,
30
+        message,
31
+    });
32
+};
33
+
34
+// import { ListResponse } from "../../../utils/ListResponse";
35
+// import { formatISOWithoutTimezone } from "../../../utils/FormatDate";
36
+// import { getUserNameById } from "../../../utils/CheckUserKeycloak";
37
+
38
+// // Jika tahu struktur data vendor, ganti `any` dengan interface Vendor
39
+// interface Vendor {
40
+//     createdAt: Date | string | null;
41
+//     updatedAt: Date | string | null;
42
+//     [key: string]: any; // untuk properti lainnya
43
+// }
44
+
45
+// const transformVendorList = async (data: Vendor[] = []): Promise<Vendor[]> => {
46
+//     return Promise.all(
47
+//         data.map(async ({ ...rest }) => {
48
+//             // const name = await getUserNameById(rest.created_by);
49
+
50
+//             return {
51
+//                 ...rest,
52
+//                 // user: {
53
+//                 //     id: rest.created_by,
54
+//                 //     name: name
55
+//                 // },
56
+//                 createdAt: formatISOWithoutTimezone(rest.createdAt),
57
+//                 updatedAt: formatISOWithoutTimezone(rest.updatedAt),
58
+//             };
59
+//         })
60
+//     );
61
+// };
62
+
63
+// interface VendorCollectionParams {
64
+//     req: any;
65
+//     res: any;
66
+//     data?: Vendor[];
67
+//     total?: number;
68
+//     page?: number;
69
+//     limit?: number;
70
+//     message?: string;
71
+// }
72
+
73
+// export const VendorCollection = async ({
74
+//     req,
75
+//     res,
76
+//     data = [],
77
+//     total = 0,
78
+//     page = 1,
79
+//     limit = 10,
80
+//     message = "Success",
81
+// }: VendorCollectionParams): Promise<any> => {
82
+//     const formatted = await transformVendorList(data);
83
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
84
+// };
85
+
86
+
87
+// const { ListResponse } = require("../../../utils/ListResponse");
88
+// const { formatISOWithoutTimezone } = require("../../../utils/FormatDate.js");
89
+// const { getUserNameById } = require("../../../utils/CheckUserKeycloak");
90
+
91
+// const transformVendorList = async (data = []) => {
92
+//     return Promise.all(data.map(async ({ ...rest }) => {
93
+//         // const name = await getUserNameById(created_by);
94
+
95
+//         return {
96
+//             ...rest,
97
+//             // user: {
98
+//             //     id: created_by,
99
+//             //     name: name
100
+//             // },
101
+//             createdAt: formatISOWithoutTimezone(rest.createdAt),
102
+//             updatedAt: formatISOWithoutTimezone(rest.updatedAt)
103
+//         };
104
+//     }));
105
+// };
106
+
107
+// // Collection yang async
108
+// exports.VendorCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
109
+//     const formatted = await transformVendorList(data);
110
+
111
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
112
+// };

+ 0 - 25
src/resources/admin/vendor/VendorResource.js

@@ -1,25 +0,0 @@
1
-const { formatISOWithoutTimezone } = require("../../../utils/FormatDate");
2
-
3
-const formatItem = ({ item, userName }) => {
4
-    const { created_by, ...rest } = item;
5
-
6
-    return {
7
-        ...rest,
8
-        user: {
9
-            id: created_by,
10
-            name: userName
11
-        },
12
-        createdAt: formatISOWithoutTimezone(item.createdAt),
13
-        updatedAt: formatISOWithoutTimezone(item.updatedAt)
14
-    };
15
-};
16
-
17
-exports.VendorResource = (res, item, userName, message = 'Success') => {
18
-    const formattedData = formatItem({ item, userName });
19
-
20
-    return res.status(200).json({
21
-        success: true,
22
-        message,
23
-        data: formattedData
24
-    });
25
-};

+ 85 - 0
src/resources/admin/vendor/VendorResource.ts

@@ -0,0 +1,85 @@
1
+import { Response } from 'express';
2
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
3
+import { VendorDTO } from '../../../types/admin/vendor/VendorDTO';
4
+
5
+const formatItem = (item: VendorDTO) => ({
6
+    ...item,
7
+    createdAt: formatISOWithoutTimezone(item.createdAt),
8
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
9
+});
10
+
11
+export const VendorResource = (res: Response, data: VendorDTO, message: string = 'Success'): Response => {
12
+    const formattedData = formatItem(data);
13
+
14
+    return res.status(200).json({
15
+        success: true,
16
+        message,
17
+        data: formattedData,
18
+    });
19
+};
20
+
21
+// import { Response } from "express";
22
+// import { formatISOWithoutTimezone } from "../../../utils/FormatDate";
23
+// import { VendorDTO } from '../../../types/admin/vendor/VendorDTO';
24
+
25
+// // Kalau ada struktur pasti dari vendor, ganti `any` dengan tipe interface
26
+// interface Vendor {
27
+//     createdAt: Date | string | null;
28
+//     updatedAt: Date | string | null;
29
+//     [key: string]: any;
30
+// }
31
+
32
+// const formatItem = ({ item }: { item: Vendor }): Vendor => {
33
+//     const { ...rest } = item;
34
+
35
+//     return {
36
+//         ...rest,
37
+//         // user: {
38
+//         //     id: item.created_by,
39
+//         //     name: userName
40
+//         // },
41
+//         createdAt: formatISOWithoutTimezone(item.createdAt),
42
+//         updatedAt: formatISOWithoutTimezone(item.updatedAt)
43
+//     };
44
+// };
45
+
46
+// export const VendorResource = (
47
+//     res: Response,
48
+//     item: Vendor,
49
+//     message = "Success"
50
+// ): Response => {
51
+//     const formattedData = formatItem({ item });
52
+
53
+//     return res.status(200).json({
54
+//         success: true,
55
+//         message,
56
+//         data: formattedData
57
+//     });
58
+// };
59
+
60
+
61
+// const { formatISOWithoutTimezone } = require("../../../utils/FormatDate");
62
+
63
+// const formatItem = ({ item }) => {
64
+//     const { ...rest } = item;
65
+
66
+//     return {
67
+//         ...rest,
68
+//         // user: {
69
+//         //     id: created_by,
70
+//         //     name: userName
71
+//         // },
72
+//         createdAt: formatISOWithoutTimezone(item.createdAt),
73
+//         updatedAt: formatISOWithoutTimezone(item.updatedAt)
74
+//     };
75
+// };
76
+
77
+// exports.VendorResource = (res, item, message = 'Success') => {
78
+//     const formattedData = formatItem({ item });
79
+
80
+//     return res.status(200).json({
81
+//         success: true,
82
+//         message,
83
+//         data: formattedData
84
+//     });
85
+// };

+ 100 - 0
src/resources/admin/vendor_experience/VendorExperienceCollection.ts

@@ -0,0 +1,100 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatDateOnly, formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { VendorExperienceDTO } from '../../../types/admin/vendor_experience/VendorExperienceDTO';
5
+
6
+const formatItem = (item: VendorExperienceDTO) => ({
7
+    ...item,
8
+    contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
9
+    contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
10
+    contract_start_date: formatDateOnly(item.contract_start_date),
11
+    contract_expired_date: formatDateOnly(item.contract_expired_date),
12
+    createdAt: formatISOWithoutTimezone(item.createdAt),
13
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
14
+});
15
+
16
+export const VendorExperienceCollection = (req: Request, res: Response, data: VendorExperienceDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
17
+    const formattedData = data.map(formatItem);
18
+
19
+    if (typeof total !== 'number') {
20
+        return res.status(200).json({
21
+            success: true,
22
+            message,
23
+            data: Array.isArray(formattedData),
24
+        });
25
+    }
26
+
27
+    return ListResponse({
28
+        req,
29
+        res,
30
+        data: formattedData,
31
+        total,
32
+        page,
33
+        limit,
34
+        message,
35
+    });
36
+};
37
+
38
+// import { Request, Response } from 'express';
39
+// import { ListResponse } from '../../../utils/ListResponse';
40
+// import { formatDateOnly, formatISOWithoutTimezone } from '../../../utils/FormatDate';
41
+// import { VendorHistoryDTO } from '../../../types/VendorHistoryDTO';
42
+
43
+// const formatItem = (item: VendorHistoryDTO): VendorHistoryDTO => ({
44
+//     ...item,
45
+//     contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
46
+//     contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
47
+//     contract_start_date: formatDateOnly(item.contract_start_date),
48
+//     contract_expired_date: formatDateOnly(item.contract_expired_date),
49
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
50
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
51
+// });
52
+
53
+// export const VendorExperienceCollection = (
54
+//     req: Request,
55
+//     res: Response,
56
+//     data: any[] = [],
57
+//     total: number | null = null,
58
+//     page: number = 1,
59
+//     limit: number = 10,
60
+//     message: string = 'Success'
61
+// ): Response => {
62
+//     const formattedData: VendorHistoryDTO[] = data.map(formatItem);
63
+
64
+//     if (typeof total !== 'number') {
65
+//         return res.status(200).json({
66
+//             success: true,
67
+//             message,
68
+//             data: Array.isArray(formattedData),
69
+//         });
70
+//     }
71
+
72
+//     return ListResponse({ req, res, data: formattedData, total, page, limit, message });
73
+// };
74
+
75
+// const { ListResponse } = require("../../../utils/ListResponse.js");
76
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
77
+
78
+// const formatItem = (item) => ({
79
+//     ...item,
80
+//     contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
81
+//     contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
82
+//     contract_start_date: formatDateOnly(item.contract_start_date),
83
+//     contract_expired_date: formatDateOnly(item.contract_expired_date),
84
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
85
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
86
+// });
87
+
88
+// exports.VendorExperienceCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
89
+//     const formattedData = data.map(formatItem);
90
+
91
+//     if (typeof total !== 'number') {
92
+//         return res.status(200).json({
93
+//             success: true,
94
+//             message,
95
+//             data: Array.isArray(formattedData)
96
+//         });
97
+//     }
98
+
99
+//     return ListResponse({ req, res, data: formattedData, total, page, limit, message });
100
+// };

+ 105 - 0
src/resources/admin/vendor_experience/VendorExperienceResource.ts

@@ -0,0 +1,105 @@
1
+import { Response } from 'express';
2
+import { formatDateOnly, formatISOWithoutTimezone } from '../../../utils/FormatDate';
3
+import { VendorExperienceDTO } from '../../../types/admin/vendor_experience/VendorExperienceDTO';
4
+
5
+export const VendorExperienceResource = (res: Response, data: VendorExperienceDTO, message: string = 'Success'): Response => {
6
+    const { vendor_id, ...restData } = data;
7
+
8
+    const formatted = {
9
+        ...restData,
10
+        vendor: data.vendor
11
+            ? {
12
+                id: data.vendor.id,
13
+                name: data.vendor.name,
14
+                name_pt: data.vendor.name_pt,
15
+                strengths: data.vendor.strengths,
16
+                weaknesses: data.vendor.weaknesses,
17
+                website: data.vendor.website,
18
+                created_by: data.vendor.created_by,
19
+            }
20
+            : null,
21
+        contract_start_date: formatDateOnly(data.contract_start_date),
22
+        contract_expired_date: formatDateOnly(data.contract_expired_date),
23
+        // contract_value_min: Number(data.contract_value_min),
24
+        // contract_value_max: Number(data.contract_value_max),
25
+        contract_value_min: data.contract_value_min !== null ? Number(data.contract_value_min) : null,
26
+        contract_value_max: data.contract_value_max !== null ? Number(data.contract_value_max) : null,
27
+        createdAt: formatISOWithoutTimezone(data.createdAt),
28
+        updatedAt: formatISOWithoutTimezone(data.updatedAt),
29
+    };
30
+
31
+    return res.status(200).json({
32
+        success: true,
33
+        message,
34
+        data: formatted,
35
+    });
36
+};
37
+
38
+// src/resources/VendorExperienceResource.ts
39
+// import { Response } from 'express';
40
+// import { VendorHistoryDTO } from '../../../types/VendorHistoryDTO';
41
+// import { formatDateOnly, formatISOWithoutTimezone } from '../../../utils/FormatDate';
42
+
43
+// export const formatVendorExperience = (item: VendorHistoryDTO): VendorHistoryDTO => ({
44
+//     ...item,
45
+//     contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
46
+//     contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
47
+//     contract_start_date: formatDateOnly(item.contract_start_date),
48
+//     contract_expired_date: formatDateOnly(item.contract_expired_date),
49
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
50
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
51
+// });
52
+
53
+// export const VendorExperienceResource = (res: Response, data: any, message: string) => {
54
+//     const { vendor_id, ...restData } = data;
55
+
56
+//     const formatted = {
57
+//         ...restData,
58
+//         vendor: data.vendor
59
+//             ? {
60
+//                 id: data.vendor.id,
61
+//                 name: data.vendor.name,
62
+//                 name_pt: data.vendor.name_pt,
63
+//                 strengths: data.vendor.strengths,
64
+//                 weaknesses: data.vendor.weaknesses,
65
+//                 website: data.vendor.website,
66
+//                 created_by: data.vendor.created_by,
67
+//             }
68
+//             : null,
69
+//         contract_start_date: formatDateOnly(data.contract_start_date),
70
+//         contract_expired_date: formatDateOnly(data.contract_expired_date),
71
+//         contract_value_min: Number(data.contract_value_min),
72
+//         contract_value_max: Number(data.contract_value_max),
73
+//         createdAt: formatISOWithoutTimezone(data.createdAt),
74
+//         updatedAt: formatISOWithoutTimezone(data.updatedAt),
75
+//     };
76
+
77
+//     return res.status(200).json({
78
+//         success: true,
79
+//         message,
80
+//         data: formatted,
81
+//     });
82
+// };
83
+
84
+
85
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
86
+
87
+// const formatItem = (item) => ({
88
+//     ...item,
89
+//     contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
90
+//     contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
91
+//     contract_start_date: formatDateOnly(item.contract_start_date),
92
+//     contract_expired_date: formatDateOnly(item.contract_expired_date),
93
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
94
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
95
+// });
96
+
97
+// exports.VendorExperienceResource = (res, data, message = 'Success') => {
98
+//     const formattedData = formatItem(data);
99
+
100
+//     return res.status(200).json({
101
+//         success: true,
102
+//         message,
103
+//         data: formattedData
104
+//     });
105
+// };

+ 0 - 26
src/resources/admin/vendor_history/VendorExperienceCollection.js

@@ -1,26 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse.js");
2
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
3
-
4
-const formatItem = (item) => ({
5
-    ...item,
6
-    contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
7
-    contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
8
-    contract_start_date: formatDateOnly(item.contract_start_date),
9
-    contract_expired_date: formatDateOnly(item.contract_expired_date),
10
-    createdAt: formatISOWithoutTimezone(item.createdAt),
11
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
12
-});
13
-
14
-exports.VendorHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
15
-    const formattedData = data.map(formatItem);
16
-
17
-    if (typeof total !== 'number') {
18
-        return res.status(200).json({
19
-            success: true,
20
-            message,
21
-            data: Array.isArray(formattedData)
22
-        });
23
-    }
24
-
25
-    return ListResponse({ req, res, data: formattedData, total, page, limit, message });
26
-};

+ 0 - 21
src/resources/admin/vendor_history/VendorExperienceResource.js

@@ -1,21 +0,0 @@
1
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
2
-
3
-const formatItem = (item) => ({
4
-    ...item,
5
-    contract_value_min: item.contract_value_min !== null ? Number(item.contract_value_min) : null,
6
-    contract_value_max: item.contract_value_max !== null ? Number(item.contract_value_max) : null,
7
-    contract_start_date: formatDateOnly(item.contract_start_date),
8
-    contract_expired_date: formatDateOnly(item.contract_expired_date),
9
-    createdAt: formatISOWithoutTimezone(item.createdAt),
10
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
11
-});
12
-
13
-exports.VendorHistoriResource = (res, data, message = 'Success') => {
14
-    const formattedData = formatItem(data);
15
-
16
-    return res.status(200).json({
17
-        success: true,
18
-        message,
19
-        data: formattedData
20
-    });
21
-};

+ 0 - 7
src/resources/auth/LoginResource.js

@@ -1,7 +0,0 @@
1
-exports.LoginResource = (res, data, message = 'Success') => {
2
-    return res.status(200).json({
3
-        success: true,
4
-        message,
5
-        data
6
-    });
7
-};

+ 0 - 8
src/resources/auth/UserResource.js

@@ -1,8 +0,0 @@
1
-exports.UserResource = (res, data, message = 'Success') => {
2
-    return res.status(200).json({
3
-        success: true,
4
-        message,
5
-        // data: Array.isArray(data) ? data : { ...data }
6
-        data
7
-    });
8
-};

+ 0 - 22
src/resources/sales/area/UserAreaCollection.js

@@ -1,22 +0,0 @@
1
-const { getUserNameById } = require("../../../utils/CheckUserKeycloak");
2
-const { ListResponse } = require("../../../utils/ListResponse");
3
-
4
-const transformArea = async (data = []) => {
5
-    return Promise.all(data.map(async ({ user_id, ...rest }) => {
6
-        const name = await getUserNameById(user_id);
7
-
8
-        return {
9
-            ...rest,
10
-            user: {
11
-                id: user_id,
12
-                name: name
13
-            },
14
-        };
15
-    }));
16
-};
17
-
18
-exports.UserAreaCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
19
-    const formatted = await transformArea(data);
20
-
21
-    return ListResponse({ req, res, data: formatted, total, page, limit, message });
22
-};

+ 106 - 0
src/resources/sales/area/UserAreaCollection.ts

@@ -0,0 +1,106 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
4
+import { AreaSalesDTO } from '../../../types/sales/area_sales/AreaSalesDTO';
5
+
6
+const formatItem = (item: AreaSalesDTO) => ({
7
+    ...item,
8
+    createdAt: formatISOWithoutTimezone(item.createdAt),
9
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
+});
11
+
12
+export const UserAreaCollection = (req: Request, res: Response, data: AreaSalesDTO[] = [], total: number | null = null, page: number = 1, limit: number = 10, message: string = 'Success'): Response => {
13
+    const formattedData = data.map(formatItem);
14
+
15
+    if (typeof total !== 'number') {
16
+        return res.status(200).json({
17
+            success: true,
18
+            message,
19
+            data: Array.isArray(formattedData),
20
+        });
21
+    }
22
+
23
+    return ListResponse({
24
+        req,
25
+        res,
26
+        data: formattedData,
27
+        total,
28
+        page,
29
+        limit,
30
+        message,
31
+    });
32
+};
33
+
34
+// import { Request, Response } from 'express';
35
+// import { ListResponse } from '../../../utils/ListResponse';
36
+// import { getUserNameById } from '../../../utils/CheckUserKeycloak';
37
+// import { formatISOWithoutTimezone } from '../../../utils/FormatDate';
38
+
39
+// interface Province {
40
+//     id: string;
41
+//     name: string;
42
+// }
43
+
44
+// interface Area {
45
+//     id: string;
46
+//     province: Province;
47
+//     createdAt: string | Date | null;
48
+//     updatedAt: string | Date | null;
49
+// }
50
+
51
+// interface UserAreaCollectionParams {
52
+//     req: Request;
53
+//     res: Response;
54
+//     data?: Area[];
55
+//     total?: number;
56
+//     page?: number;
57
+//     limit?: number;
58
+//     message?: string;
59
+// }
60
+
61
+// const transformArea = async (data: Area[] = []): Promise<Area[]> => {
62
+//     return Promise.all(data.map(async (item) => {
63
+//         return {
64
+//             ...item,
65
+//             createdAt: formatISOWithoutTimezone(item.createdAt),
66
+//             updatedAt: formatISOWithoutTimezone(item.updatedAt),
67
+//         };
68
+//     }));
69
+// };
70
+
71
+// export const UserAreaCollection = async ({
72
+//     req,
73
+//     res,
74
+//     data = [],
75
+//     total = 0,
76
+//     page = 1,
77
+//     limit = 10,
78
+//     message = 'Success',
79
+// }: UserAreaCollectionParams): Promise<Response> => {
80
+//     const formatted = await transformArea(data);
81
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
82
+// };
83
+
84
+
85
+// const { getUserNameById } = require("../../../utils/CheckUserKeycloak");
86
+// const { ListResponse } = require("../../../utils/ListResponse");
87
+
88
+// const transformArea = async (data = []) => {
89
+//     return Promise.all(data.map(async ({ ...rest }) => {
90
+//         // const name = await getUserNameById(user_id);
91
+
92
+//         return {
93
+//             ...rest,
94
+//             // user: {
95
+//             //     id: user_id,
96
+//             //     name: name
97
+//             // },
98
+//         };
99
+//     }));
100
+// };
101
+
102
+// exports.UserAreaCollection = async ({ req, res, data = [], total = 0, page = 1, limit = 10, message = 'Success' }) => {
103
+//     const formatted = await transformArea(data);
104
+
105
+//     return ListResponse({ req, res, data: formatted, total, page, limit, message });
106
+// };

+ 0 - 24
src/resources/sales/executives_history/ExecutivesHistoriCollection.js

@@ -1,24 +0,0 @@
1
-const { ListResponse } = require("../../../utils/ListResponse");
2
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
3
-
4
-const formatItem = (item) => ({
5
-    ...item,
6
-    start_term: formatDateOnly(item.start_term),
7
-    end_term: formatDateOnly(item.end_term),
8
-    createdAt: formatISOWithoutTimezone(item.createdAt),
9
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
-});
11
-
12
-exports.ExecutivesHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
13
-    const formattedData = data.map(formatItem);
14
-
15
-    if (typeof total !== 'number') {
16
-        return res.status(200).json({
17
-            success: true,
18
-            message,
19
-            data: Array.isArray(formattedData)
20
-        });
21
-    }
22
-
23
-    return ListResponse({ req, res, data: formattedData, total, page, limit, message });
24
-};

+ 60 - 0
src/resources/sales/executives_history/ExecutivesHistoriCollection.ts

@@ -0,0 +1,60 @@
1
+import { Request, Response } from 'express';
2
+import { ListResponse } from '../../../utils/ListResponse';
3
+import { formatISOWithoutTimezone, formatDateOnly } from '../../../utils/FormatDate';
4
+import { ExecutiveHistoryDTO } from '../../../types/sales/executives_history/ExecutivesHistoryDTO';
5
+
6
+const formatItem = (item: ExecutiveHistoryDTO): ExecutiveHistoryDTO => ({
7
+    ...item,
8
+    start_term: formatDateOnly(item.start_term),
9
+    end_term: formatDateOnly(item.end_term),
10
+    createdAt: formatISOWithoutTimezone(item.createdAt),
11
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
12
+});
13
+
14
+export const ExecutivesHistoriCollection = (
15
+    req: Request,
16
+    res: Response,
17
+    data: ExecutiveHistoryDTO[] = [],
18
+    total: number | null = null,
19
+    page = 1,
20
+    limit = 10,
21
+    message = 'Success'
22
+): Response => {
23
+    const formattedData = data.map(formatItem);
24
+
25
+    if (typeof total !== 'number') {
26
+        return res.status(200).json({
27
+            success: true,
28
+            message,
29
+            data: Array.isArray(formattedData)
30
+        });
31
+    }
32
+
33
+    return ListResponse({ req, res, data: formattedData, total, page, limit, message });
34
+};
35
+
36
+
37
+// const { ListResponse } = require("../../../utils/ListResponse");
38
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
39
+
40
+// const formatItem = (item) => ({
41
+//     ...item,
42
+//     start_term: formatDateOnly(item.start_term),
43
+//     end_term: formatDateOnly(item.end_term),
44
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
45
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
46
+// });
47
+
48
+// exports.ExecutivesHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
49
+//     const formattedData = data.map(formatItem);
50
+
51
+//     if (typeof total !== 'number') {
52
+//         return res.status(200).json({
53
+//             success: true,
54
+//             message,
55
+//             data: Array.isArray(formattedData)
56
+//         });
57
+//     }
58
+
59
+//     return ListResponse({ req, res, data: formattedData, total, page, limit, message });
60
+// };

+ 0 - 19
src/resources/sales/executives_history/ExecutivesHistoriResource.js

@@ -1,19 +0,0 @@
1
-const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
2
-
3
-const formatItem = (item) => ({
4
-    ...item,
5
-    start_term: formatDateOnly(item.start_term),
6
-    end_term: formatDateOnly(item.end_term),
7
-    createdAt: formatISOWithoutTimezone(item.createdAt),
8
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
9
-});
10
-
11
-exports.ExecutivesHistoriResource = (res, data, message = 'Success') => {
12
-    const formattedData = formatItem(data);
13
-
14
-    return res.status(200).json({
15
-        success: true,
16
-        message,
17
-        data: formattedData
18
-    });
19
-};

+ 45 - 0
src/resources/sales/executives_history/ExecutivesHistoriResource.ts

@@ -0,0 +1,45 @@
1
+import { Response } from 'express';
2
+import { formatISOWithoutTimezone, formatDateOnly } from '../../../utils/FormatDate';
3
+import { ExecutiveHistoryDTO } from '../../../types/sales/executives_history/ExecutivesHistoryDTO';
4
+
5
+const formatItem = (item: ExecutiveHistoryDTO): ExecutiveHistoryDTO => ({
6
+    ...item,
7
+    start_term: formatDateOnly(item.start_term),
8
+    end_term: formatDateOnly(item.end_term),
9
+    createdAt: formatISOWithoutTimezone(item.createdAt),
10
+    updatedAt: formatISOWithoutTimezone(item.updatedAt),
11
+});
12
+
13
+export const ExecutivesHistoriResource = (
14
+    res: Response,
15
+    data: ExecutiveHistoryDTO,
16
+    message = 'Success'
17
+): Response => {
18
+    const formattedData = formatItem(data);
19
+
20
+    return res.status(200).json({
21
+        success: true,
22
+        message,
23
+        data: formattedData
24
+    });
25
+};
26
+
27
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate");
28
+
29
+// const formatItem = (item) => ({
30
+//     ...item,
31
+//     start_term: formatDateOnly(item.start_term),
32
+//     end_term: formatDateOnly(item.end_term),
33
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
34
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
35
+// });
36
+
37
+// exports.ExecutivesHistoriResource = (res, data, message = 'Success') => {
38
+//     const formattedData = formatItem(data);
39
+
40
+//     return res.status(200).json({
41
+//         success: true,
42
+//         message,
43
+//         data: formattedData
44
+//     });
45
+// };

+ 0 - 0
src/resources/sales/hospital/HospitalCollection.js


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff