瀏覽代碼

solve bug hospital, executive history & vendor experience sales admin

pearlgw 1 月之前
父節點
當前提交
476a5f200a
共有 25 個文件被更改,包括 766 次插入508 次删除
  1. 7 7
      src/controllers/admin/VendorExperienceController.js
  2. 14 14
      src/controllers/sales/VendorHistoryController.js
  3. 13 0
      src/repository/admin/CityRepository.js
  4. 2 2
      src/repository/admin/ExecutivesHistoryRepository.js
  5. 11 0
      src/repository/admin/ProvinceRepository.js
  6. 2 2
      src/repository/sales/ExecutivesHistoryRepository.js
  7. 2 4
      src/repository/sales/HospitalRepository.js
  8. 86 0
      src/repository/sales/VendorExperienceRepository.js
  9. 0 134
      src/repository/sales/VendorHistoryRepository.js
  10. 1 1
      src/resources/admin/vendor_history/VendorExperienceCollection.js
  11. 1 1
      src/resources/admin/vendor_history/VendorExperienceResource.js
  12. 51 0
      src/resources/sales/vendor_experience/VendorExperienceCollection.js
  13. 1 1
      src/resources/sales/vendor_history/VendorHistoriResource.js
  14. 0 24
      src/resources/sales/vendor_history/VendorHistoriCollection.js
  15. 6 6
      src/routes/sales/HospitalRoute.js
  16. 10 0
      src/services/admin/CityService.js
  17. 24 0
      src/services/admin/ExecutivesHistoryService.js
  18. 10 0
      src/services/admin/ProvinceService.js
  19. 3 3
      src/services/admin/VendorExperienceService.js
  20. 24 0
      src/services/sales/ExecutivesHistoryService.js
  21. 2 2
      src/services/sales/HospitalService.js
  22. 469 0
      src/services/sales/VendorExperienceService.js
  23. 0 212
      src/services/sales/VendorHistoryService.js
  24. 27 0
      src/validators/sales/vendor_experience/VendorExperienceValidators.js
  25. 0 95
      src/validators/sales/vendor_history/VendorHistoriValidators.js

+ 7 - 7
src/controllers/admin/VendorExperienceController.js

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

+ 14 - 14
src/controllers/sales/VendorHistoryController.js

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

+ 13 - 0
src/repository/admin/CityRepository.js

@@ -48,6 +48,19 @@ const CityRepository = {
48 48
         });
49 49
     },
50 50
 
51
+
52
+    findByNameAndProvinceId: async (name, province_id) => {
53
+        return await prisma.city.findFirst({
54
+            where: {
55
+                name: {
56
+                    equals: name,
57
+                    mode: "insensitive"
58
+                },
59
+                province_id: province_id
60
+            }
61
+        });
62
+    },
63
+
51 64
     create: async (data) => {
52 65
         return prisma.city.create({ data });
53 66
     },

+ 2 - 2
src/repository/admin/ExecutivesHistoryRepository.js

@@ -29,7 +29,7 @@ const ExecutivesHistoryRepository = {
29 29
                             }
30 30
                         },
31 31
                         address: true,
32
-                        simrs_type: true,
32
+                        // simrs_type: true,
33 33
                         contact: true,
34 34
                         image: true,
35 35
                         progress_status: true,
@@ -80,7 +80,7 @@ const ExecutivesHistoryRepository = {
80 80
                             }
81 81
                         },
82 82
                         address: true,
83
-                        simrs_type: true,
83
+                        // simrs_type: true,
84 84
                         contact: true,
85 85
                         image: true,
86 86
                         progress_status: true,

+ 11 - 0
src/repository/admin/ProvinceRepository.js

@@ -35,6 +35,17 @@ const ProvinceRepository = {
35 35
         });
36 36
     },
37 37
 
38
+    findByName: async (name) => {
39
+        return await prisma.province.findFirst({
40
+            where: {
41
+                name: {
42
+                    equals: name,
43
+                    mode: "insensitive"
44
+                }
45
+            }
46
+        });
47
+    },
48
+
38 49
     create: async (data) => {
39 50
         return prisma.province.create({ data });
40 51
     },

+ 2 - 2
src/repository/sales/ExecutivesHistoryRepository.js

@@ -29,7 +29,7 @@ const ExecutivesHistoryRepository = {
29 29
                             }
30 30
                         },
31 31
                         address: true,
32
-                        simrs_type: true,
32
+                        // simrs_type: true,
33 33
                         contact: true,
34 34
                         image: true,
35 35
                         progress_status: true,
@@ -86,7 +86,7 @@ const ExecutivesHistoryRepository = {
86 86
                             }
87 87
                         },
88 88
                         address: true,
89
-                        simrs_type: true,
89
+                        // simrs_type: true,
90 90
                         contact: true,
91 91
                         image: true,
92 92
                         progress_status: true,

+ 2 - 4
src/repository/sales/HospitalRepository.js

@@ -16,7 +16,6 @@ const HospitalRepository = {
16 16
                 province: { select: { id: true, name: true } },
17 17
                 city: { select: { id: true, name: true } },
18 18
                 address: true,
19
-                simrs_type: true,
20 19
                 contact: true,
21 20
                 image: true,
22 21
                 progress_status: true,
@@ -27,7 +26,7 @@ const HospitalRepository = {
27 26
                 created_by: true,
28 27
                 createdAt: true,
29 28
                 updatedAt: true,
30
-                vendor_histories: {
29
+                vendor_experiences: {
31 30
                     where: {
32 31
                         status: "active",
33 32
                         deletedAt: null
@@ -80,7 +79,6 @@ const HospitalRepository = {
80 79
                 province: { select: { id: true, name: true } },
81 80
                 city: { select: { id: true, name: true } },
82 81
                 address: true,
83
-                simrs_type: true,
84 82
                 contact: true,
85 83
                 image: true,
86 84
                 progress_status: true,
@@ -91,7 +89,7 @@ const HospitalRepository = {
91 89
                 created_by: true,
92 90
                 createdAt: true,
93 91
                 updatedAt: true,
94
-                vendor_histories: {
92
+                vendor_experiences: {
95 93
                     where: {
96 94
                         status: "active",
97 95
                         deletedAt: null

+ 86 - 0
src/repository/sales/VendorExperienceRepository.js

@@ -0,0 +1,86 @@
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
+                vendor: {
13
+                    select: {
14
+                        id: true,
15
+                        name: true,
16
+                        name_pt: true,
17
+                        strengths: true,
18
+                        weaknesses: true,
19
+                        website: true,
20
+                        created_by: true,
21
+                    }
22
+                },
23
+                status: true,
24
+                simrs_type: true,
25
+                contract_value_min: true,
26
+                contract_value_max: true,
27
+                contract_start_date: true,
28
+                contract_expired_date: true,
29
+                positive_notes: true,
30
+                negative_notes: true,
31
+                createdAt: true,
32
+                updatedAt: true,
33
+            },
34
+        });
35
+    },
36
+
37
+    countAll: async (where) => {
38
+        return prisma.vendorExperience.count({ where });
39
+    },
40
+
41
+    findById: async (id) => {
42
+        return prisma.vendorExperience.findFirst({
43
+            where: {
44
+                id,
45
+                deletedAt: null
46
+            },
47
+            select: {
48
+                id: true,
49
+                vendor: {
50
+                    select: {
51
+                        id: true,
52
+                        name: true,
53
+                        name_pt: true,
54
+                        strengths: true,
55
+                        weaknesses: true,
56
+                        website: true,
57
+                        created_by: true,
58
+                    }
59
+                },
60
+                status: true,
61
+                simrs_type: true,
62
+                contract_value_min: true,
63
+                contract_value_max: true,
64
+                contract_start_date: true,
65
+                contract_expired_date: true,
66
+                positive_notes: true,
67
+                negative_notes: true,
68
+                createdAt: true,
69
+                updatedAt: true,
70
+            },
71
+        });
72
+    },
73
+
74
+    create: async (data) => {
75
+        return prisma.vendorExperience.create({ data });
76
+    },
77
+
78
+    update: async (id, data) => {
79
+        return prisma.vendorExperience.update({
80
+            where: { id },
81
+            data
82
+        });
83
+    },
84
+};
85
+
86
+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;

+ 1 - 1
src/resources/admin/vendor_history/VendorExperienceCollection.js

@@ -11,7 +11,7 @@ const formatItem = (item) => ({
11 11
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
12 12
 });
13 13
 
14
-exports.VendorHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
14
+exports.VendorExperienceCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
15 15
     const formattedData = data.map(formatItem);
16 16
 
17 17
     if (typeof total !== 'number') {

+ 1 - 1
src/resources/admin/vendor_history/VendorExperienceResource.js

@@ -10,7 +10,7 @@ const formatItem = (item) => ({
10 10
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
11 11
 });
12 12
 
13
-exports.VendorHistoriResource = (res, data, message = 'Success') => {
13
+exports.VendorExperienceResource = (res, data, message = 'Success') => {
14 14
     const formattedData = formatItem(data);
15 15
 
16 16
     return res.status(200).json({

+ 51 - 0
src/resources/sales/vendor_experience/VendorExperienceCollection.js

@@ -0,0 +1,51 @@
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.VendorExperienceCollection = (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
+};
27
+
28
+// const { ListResponse } = require("../../../utils/ListResponse");
29
+// const { formatISOWithoutTimezone, formatDateOnly } = require("../../../utils/FormatDate.js");
30
+
31
+// const formatItem = (item) => ({
32
+//     ...item,
33
+//     contract_date: formatDateOnly(item.contract_date),
34
+//     contract_expired_date: formatDateOnly(item.contract_expired_date),
35
+//     createdAt: formatISOWithoutTimezone(item.createdAt),
36
+//     updatedAt: formatISOWithoutTimezone(item.updatedAt),
37
+// });
38
+
39
+// exports.VendorHistoriCollection = (req, res, data = [], total = null, page = 1, limit = 10, message = 'Success') => {
40
+//     const formattedData = data.map(formatItem);
41
+
42
+//     if (typeof total !== 'number') {
43
+//         return res.status(200).json({
44
+//             success: true,
45
+//             message,
46
+//             data: Array.isArray(formattedData)
47
+//         });
48
+//     }
49
+
50
+//     return ListResponse({ req, res, data: formattedData, total, page, limit, message });
51
+// };

+ 1 - 1
src/resources/sales/vendor_history/VendorHistoriResource.js

@@ -8,7 +8,7 @@ const formatItem = (item) => ({
8 8
     updatedAt: formatISOWithoutTimezone(item.updatedAt),
9 9
 });
10 10
 
11
-exports.VendorHistoriResource = (res, data, message = 'Success') => {
11
+exports.VendorExperienceResource = (res, data, message = 'Success') => {
12 12
     const formattedData = formatItem(data);
13 13
 
14 14
     return res.status(200).json({

+ 0 - 24
src/resources/sales/vendor_history/VendorHistoriCollection.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
-    contract_date: formatDateOnly(item.contract_date),
7
-    contract_expired_date: formatDateOnly(item.contract_expired_date),
8
-    createdAt: formatISOWithoutTimezone(item.createdAt),
9
-    updatedAt: formatISOWithoutTimezone(item.updatedAt),
10
-});
11
-
12
-exports.VendorHistoriCollection = (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
-};

+ 6 - 6
src/routes/sales/HospitalRoute.js

@@ -1,7 +1,7 @@
1 1
 const express = require('express')
2 2
 const router = express.Router()
3 3
 const hospitalController = require('../../controllers/sales/HospitalController.js')
4
-const vendorHistoryController = require('../../controllers/sales/VendorHistoryController.js')
4
+const vendorExperienceController = require('../../controllers/sales/VendorExperienceController.js')
5 5
 const executivesHistoryController = require('../../controllers/sales/ExecutivesHistoryController.js')
6 6
 const statusHistoriesController = require('../../controllers/sales/StatusHistoryController.js')
7 7
 // const verifyJWT = require('../../middleware/VerifyJWT.js');
@@ -37,11 +37,11 @@ router.patch('/:id', [keycloak.protect(), extractToken, checkRoles(['sales'])],
37 37
 router.get('/:id', [keycloak.protect(), extractToken, checkRoles(['sales'])], hospitalController.showHospital);
38 38
 
39 39
 // Vendor History
40
-router.get('/:id/vendor-experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorHistoryController.getAllVendorHistory);
41
-router.post('/:id/vendor-experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorHistoryController.storeVendorHistory);
42
-router.get('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorHistoryController.showVendorHistory);
43
-router.patch('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorHistoryController.updateVendorHistory);
44
-router.delete('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorHistoryController.deleteVendorHistory);
40
+router.get('/:id/vendor-experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorExperienceController.getAllVendorHistory);
41
+router.post('/:id/vendor-experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorExperienceController.storeVendorHistory);
42
+router.get('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorExperienceController.showVendorHistory);
43
+router.patch('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorExperienceController.updateVendorHistory);
44
+router.delete('/:id/vendor-experience/:id_vendor_experience', [keycloak.protect(), extractToken, checkRoles(['sales'])], vendorExperienceController.deleteVendorHistory);
45 45
 
46 46
 // Executives History
47 47
 router.get('/:id/executives-history', [keycloak.protect(), extractToken, checkRoles(['sales'])], executivesHistoryController.getAllExecutivesHistory);

+ 10 - 0
src/services/admin/CityService.js

@@ -43,6 +43,11 @@ exports.storeCityService = async (validateData, req) => {
43 43
         throw new HttpException('Province not found', 404);
44 44
     }
45 45
 
46
+    const existingProvince = await CityRepository.findByNameAndProvinceId(validateData.name, validateData.province_id);
47
+    if (existingProvince) {
48
+        throw new HttpException("City with this name and province ID already exists and cannot be duplicated.", 400);
49
+    }
50
+
46 51
     const data = await CityRepository.create(validateData);
47 52
     await createLog(req, data);
48 53
 };
@@ -60,6 +65,11 @@ exports.updateCityService = async (validateData, id, req) => {
60 65
         }
61 66
     }
62 67
 
68
+    const existingProvince = await CityRepository.findByNameAndProvinceId(validateData.name, validateData.province_id);
69
+    if (existingProvince) {
70
+        throw new HttpException("City with this name and province ID already exists and cannot be duplicated.", 400);
71
+    }
72
+
63 73
     const data = await CityRepository.update(id, validateData);
64 74
     await updateLog(req, data);
65 75
 };

+ 24 - 0
src/services/admin/ExecutivesHistoryService.js

@@ -66,6 +66,18 @@ exports.storeExecutivesHistoryService = async (validateData, req) => {
66 66
         throw new HttpException("Hospital not found", 404)
67 67
     }
68 68
 
69
+    if (validateData.status === "active") {
70
+        await prisma.executivesHistory.updateMany({
71
+            where: {
72
+                hospital_id: hospitalId,
73
+                status: "active"
74
+            },
75
+            data: {
76
+                status: "inactive"
77
+            }
78
+        });
79
+    }
80
+
69 81
     const payload = {
70 82
         ...validateData,
71 83
         hospital_id: hospitalId
@@ -99,6 +111,18 @@ exports.updateExecutivesHistoryService = async (validateData, req) => {
99 111
         }
100 112
     }
101 113
 
114
+    if (validateData.status === "active") {
115
+        await prisma.executivesHistory.updateMany({
116
+            where: {
117
+                hospital_id: id_hospital,
118
+                status: "active"
119
+            },
120
+            data: {
121
+                status: "inactive"
122
+            }
123
+        });
124
+    }
125
+
102 126
     const payload = {
103 127
         ...validateData,
104 128
         start_term: validateData.start_term ? new Date(validateData.start_term) : executivesHistory.start_term,

+ 10 - 0
src/services/admin/ProvinceService.js

@@ -37,6 +37,11 @@ exports.showProvinceService = async (id) => {
37 37
 };
38 38
 
39 39
 exports.storeProvinceService = async (validateData, req) => {
40
+    const existingProvince = await ProvinceRepository.findByName(validateData.name);
41
+    if (existingProvince) {
42
+        throw new HttpException("Province with this name already exists and may not be duplicated.", 400);
43
+    }
44
+
40 45
     const province = await ProvinceRepository.create(validateData);
41 46
     await createLog(req, province);
42 47
 };
@@ -47,6 +52,11 @@ exports.updateProvinceService = async (validateData, id, req) => {
47 52
         throw new HttpException("Data province not found", 404);
48 53
     }
49 54
 
55
+    const existingProvince = await ProvinceRepository.findByName(validateData.name);
56
+    if (existingProvince) {
57
+        throw new HttpException("Province with this name already exists and may not be duplicated.", 400);
58
+    }
59
+
50 60
     const data = await ProvinceRepository.update(id, validateData);
51 61
     await updateLog(req, data);
52 62
 };

+ 3 - 3
src/services/admin/VendorExperienceService.js

@@ -48,7 +48,7 @@ exports.showVendorHistoryService = async (req) => {
48 48
 
49 49
     const vendorHistory = await VendorExperienceRepository.findById(id_vendor_experience);
50 50
     if (!vendorHistory) {
51
-        throw new HttpException("Vendor history not found", 404);
51
+        throw new HttpException("Vendor experience not found", 404);
52 52
     }
53 53
 
54 54
     return vendorHistory;
@@ -160,7 +160,7 @@ exports.updateVendorHistoryService = async (validateData, req) => {
160 160
 
161 161
     const vendorHistory = await VendorExperienceRepository.findById(id_vendor_experience);
162 162
     if (!vendorHistory) {
163
-        throw new HttpException("Vendor history not found", 404);
163
+        throw new HttpException("Vendor experience not found", 404);
164 164
     }
165 165
 
166 166
     if (validateData.vendor_id) {
@@ -253,7 +253,7 @@ exports.deleteVendorHistoryService = async (req) => {
253 253
 
254 254
     const vendor = await VendorExperienceRepository.findById(id_vendor_experience);
255 255
     if (!vendor) {
256
-        throw new HttpException("Vendor history not found", 404);
256
+        throw new HttpException("Vendor experience not found", 404);
257 257
     }
258 258
 
259 259
     const data = await VendorExperienceRepository.update(id_vendor_experience, {

+ 24 - 0
src/services/sales/ExecutivesHistoryService.js

@@ -65,6 +65,18 @@ exports.storeExecutivesHistoryService = async (validateData, req) => {
65 65
         throw new HttpException("Hospital not found", 404)
66 66
     }
67 67
 
68
+    if (validateData.status === "active") {
69
+        await prisma.executivesHistory.updateMany({
70
+            where: {
71
+                hospital_id: hospitalId,
72
+                status: "active"
73
+            },
74
+            data: {
75
+                status: "inactive"
76
+            }
77
+        });
78
+    }
79
+
68 80
     const payload = {
69 81
         ...validateData,
70 82
         hospital_id: hospitalId
@@ -98,6 +110,18 @@ exports.updateExecutivesHistoryService = async (validateData, req) => {
98 110
         }
99 111
     }
100 112
 
113
+    if (validateData.status === "active") {
114
+        await prisma.executivesHistory.updateMany({
115
+            where: {
116
+                hospital_id: id_hospital,
117
+                status: "active"
118
+            },
119
+            data: {
120
+                status: "inactive"
121
+            }
122
+        });
123
+    }
124
+
101 125
     const payload = {
102 126
         ...validateData,
103 127
         start_term: validateData.start_term ? new Date(validateData.start_term) : executivesHistory.start_term,

+ 2 - 2
src/services/sales/HospitalService.js

@@ -20,7 +20,7 @@ exports.getAllHospitalByAreaService = async ({ page, limit, search, sortBy, orde
20 20
     const provinceIds = userAreas.map(ua => ua.province_id);
21 21
 
22 22
     const where = {
23
-        ...SearchFilter(search, ['name', 'province.id', 'city.id', 'type', 'ownership', 'simrs_type']),
23
+        ...SearchFilter(search, ['name', 'province.id', 'city.id', 'type', 'ownership']),
24 24
         province_id: { in: provinceIds },
25 25
         ...(province ? { province_id: province } : {}),
26 26
         ...(city ? { city_id: city } : {}),
@@ -169,7 +169,7 @@ exports.storeHospitalService = async (validateData, req) => {
169 169
         ...validateData,
170 170
         image: imagePath,
171 171
         progress_status: "cari_data",
172
-        simrs_type: "-",
172
+        // simrs_type: "-",
173 173
         created_by: creatorId,
174 174
         latitude,
175 175
         longitude,

+ 469 - 0
src/services/sales/VendorExperienceService.js

@@ -0,0 +1,469 @@
1
+const VendorExperienceRepository = require('../../repository/sales/VendorExperienceRepository.js');
2
+const HttpException = require('../../utils/HttpException.js');
3
+const prisma = require('../../prisma/PrismaClient.js');
4
+const timeLocal = require('../../utils/TimeLocal.js');
5
+const { createLog, updateLog, deleteLog } = require('../../utils/LogActivity.js');
6
+
7
+exports.getAllVendorHistoryService = async ({ page, limit, search, sortBy, orderBy }, req) => {
8
+    const skip = (page - 1) * limit;
9
+
10
+    const hospitalId = req.params.id;
11
+    const hospital = await prisma.hospital.findFirst({
12
+        where: {
13
+            id: hospitalId
14
+        }
15
+    })
16
+    if (!hospital) {
17
+        throw new HttpException("Hospital not found", 404)
18
+    }
19
+
20
+    const where = {
21
+        // ...SearchFilter(search, ['name', 'name_pt']),
22
+        hospital_id: req.params.id,
23
+        deletedAt: null
24
+    };
25
+
26
+    const [vendor_histories, total] = await Promise.all([
27
+        VendorExperienceRepository.findAll({ skip, take: limit, where, orderBy: { [sortBy]: orderBy } }),
28
+        VendorExperienceRepository.countAll(where)
29
+    ]);
30
+
31
+    return { vendor_histories, total };
32
+};
33
+
34
+exports.showVendorHistoryService = async (req) => {
35
+    const id_hospital = req.params.id;
36
+    const id_vendor_experience = req.params.id_vendor_experience;
37
+
38
+    const hospital = await prisma.hospital.findFirst({
39
+        where: {
40
+            id: id_hospital
41
+        }
42
+    })
43
+    if (!hospital) {
44
+        throw new HttpException("Hospital not found", 404)
45
+    }
46
+
47
+    const vendorHistory = await VendorExperienceRepository.findById(id_vendor_experience);
48
+    if (!vendorHistory) {
49
+        throw new HttpException("Vendor experience not found", 404);
50
+    }
51
+
52
+    return vendorHistory;
53
+};
54
+
55
+exports.storeVendorHistoryService = async (validateData, req) => {
56
+    const hospitalId = req.params.id;
57
+
58
+    const hospital = await prisma.hospital.findFirst({
59
+        where: {
60
+            id: hospitalId
61
+        }
62
+    });
63
+
64
+    if (!hospital) {
65
+        throw new HttpException("Hospital not found", 404)
66
+    }
67
+
68
+    if (validateData.vendor_id) {
69
+        const vendor = await prisma.vendor.findFirst({
70
+            where: {
71
+                id: validateData.vendor_id
72
+            }
73
+        });
74
+
75
+        if (!vendor) {
76
+            throw new HttpException("Vendor not found", 404)
77
+        }
78
+    }
79
+
80
+    const SimrsType = ["vendor", "in house", "gratis"];
81
+    if (validateData.simrs_type && !SimrsType.includes(validateData.simrs_type)) {
82
+        throw new HttpException("Simrs type must be vendor, in house, or gratis", 400);
83
+    }
84
+
85
+    if (validateData.contract_start_date && validateData.contract_expired_date) {
86
+        if (validateData.contract_start_date >= validateData.contract_expired_date) {
87
+            throw new HttpException("Contract expired date must be after contract date", 400)
88
+        }
89
+    }
90
+
91
+    if (validateData.contract_value_min && validateData.contract_value_max) {
92
+        if (validateData.contract_value_min >= validateData.contract_value_max) {
93
+            throw new HttpException("Contract value max must be after contract value min", 400)
94
+        }
95
+    }
96
+
97
+    // await prisma.hospital.update({
98
+    //     where: { id: hospitalId },
99
+    //     data: {
100
+    //         simrs_type: validateData.simrs_type
101
+    //     }
102
+    // });
103
+
104
+    if (validateData.simrs_type) {
105
+        const existingActiveVendors = await prisma.vendorExperience.findMany({
106
+            where: {
107
+                hospital_id: hospitalId,
108
+                status: "active",
109
+                deletedAt: null
110
+            }
111
+        });
112
+
113
+        if (existingActiveVendors.length > 0) {
114
+            await prisma.vendorExperience.updateMany({
115
+                where: {
116
+                    hospital_id: hospitalId,
117
+                    status: "active",
118
+                    deletedAt: null
119
+                },
120
+                data: {
121
+                    status: "inactive"
122
+                }
123
+            });
124
+        }
125
+
126
+        validateData.status = "active";
127
+    }
128
+
129
+    const payload = {
130
+        vendor_id: validateData.vendor_id,
131
+        simrs_type: validateData.simrs_type,
132
+        status: validateData.status,
133
+        contract_start_date: validateData.contract_start_date ? new Date(validateData.contract_start_date) : null,
134
+        contract_expired_date: validateData.contract_expired_date ? new Date(validateData.contract_expired_date) : null,
135
+        contract_value_min: validateData.contract_value_min ? Number(validateData.contract_value_min) : null,
136
+        contract_value_max: validateData.contract_value_max ? Number(validateData.contract_value_max) : null,
137
+        positive_notes: validateData.positive_notes,
138
+        negative_notes: validateData.negative_notes,
139
+        hospital_id: hospitalId
140
+    };
141
+
142
+    const data = await VendorExperienceRepository.create(payload);
143
+    await createLog(req, data);
144
+};
145
+
146
+exports.updateVendorHistoryService = async (validateData, req) => {
147
+    const id_hospital = req.params.id;
148
+    const id_vendor_experience = req.params.id_vendor_experience;
149
+
150
+    const hospital = await prisma.hospital.findFirst({
151
+        where: {
152
+            id: id_hospital
153
+        }
154
+    })
155
+    if (!hospital) {
156
+        throw new HttpException("Hospital not found", 404)
157
+    }
158
+
159
+    const vendorHistory = await VendorExperienceRepository.findById(id_vendor_experience);
160
+    if (!vendorHistory) {
161
+        throw new HttpException("Vendor experience not found", 404);
162
+    }
163
+
164
+    if (validateData.vendor_id) {
165
+        const existVendor = await prisma.vendor.findFirst({
166
+            where: {
167
+                id: validateData.vendor_id
168
+            }
169
+        });
170
+        if (!existVendor) {
171
+            throw new HttpException("Vendor not found", 404)
172
+        }
173
+    }
174
+
175
+    const SimrsType = ["vendor", "in house", "gratis"];
176
+    if (validateData.simrs_type && !SimrsType.includes(validateData.simrs_type)) {
177
+        throw new HttpException("Simrs type must be vendor, in house, or gratis", 400);
178
+    }
179
+
180
+    if (
181
+        validateData.simrs_type &&
182
+        vendorHistory.simrs_type === "vendor" &&
183
+        vendorHistory.vendor_id !== null &&
184
+        validateData.simrs_type !== "vendor"
185
+    ) {
186
+        await prisma.vendorExperience.update({
187
+            where: {
188
+                id: id_vendor_experience,
189
+                deletedAt: null
190
+            },
191
+            data: {
192
+                vendor_id: null
193
+            }
194
+        });
195
+    }
196
+
197
+    if (validateData.contract_start_date && validateData.contract_expired_date) {
198
+        if (validateData.contract_start_date >= validateData.contract_expired_date) {
199
+            throw new HttpException("Contract expired date must be after contract date", 400)
200
+        }
201
+    }
202
+
203
+    if (validateData.contract_value_min && validateData.contract_value_max) {
204
+        if (validateData.contract_value_min >= validateData.contract_value_max) {
205
+            throw new HttpException("Contract value max must be after contract value min", 400)
206
+        }
207
+    }
208
+
209
+    if (validateData.status === "active") {
210
+        await prisma.vendorExperience.updateMany({
211
+            where: {
212
+                hospital_id: id_hospital,
213
+                status: "active",
214
+                deletedAt: null,
215
+                NOT: { id: id_vendor_experience },
216
+            },
217
+            data: {
218
+                status: "inactive",
219
+            },
220
+        });
221
+    }
222
+
223
+    const payload = {
224
+        status: validateData.status,
225
+        contract_start_date: validateData.contract_start_date ? new Date(validateData.contract_start_date) : vendorHistory.contract_start_date,
226
+        contract_expired_date: validateData.contract_expired_date ? new Date(validateData.contract_expired_date) : vendorHistory.contract_expired_date,
227
+        contract_value_min: validateData.contract_value_min ? Number(validateData.contract_value_min) : vendorHistory.contract_value_min,
228
+        contract_value_max: validateData.contract_value_max ? Number(validateData.contract_value_max) : vendorHistory.contract_value_max,
229
+        positive_notes: validateData.positive_notes,
230
+        negative_notes: validateData.negative_notes,
231
+        simrs_type: validateData.simrs_type,
232
+        vendor_id: validateData.vendor_id,
233
+    };
234
+
235
+    const data = await VendorExperienceRepository.update(id_vendor_experience, payload);
236
+    await updateLog(req, data);
237
+};
238
+
239
+exports.deleteVendorHistoryService = async (req) => {
240
+    const id_hospital = req.params.id;
241
+    const id_vendor_experience = req.params.id_vendor_experience;
242
+
243
+    const hospital = await prisma.hospital.findFirst({
244
+        where: {
245
+            id: id_hospital
246
+        }
247
+    })
248
+    if (!hospital) {
249
+        throw new HttpException("Hospital not found", 404)
250
+    }
251
+
252
+    const vendor = await VendorExperienceRepository.findById(id_vendor_experience);
253
+    if (!vendor) {
254
+        throw new HttpException("Vendor experience not found", 404);
255
+    }
256
+
257
+    const data = await VendorExperienceRepository.update(id_vendor_experience, {
258
+        deletedAt: timeLocal.now().toDate()
259
+    });
260
+
261
+    await deleteLog(req, data);
262
+};
263
+
264
+// exports.getAllVendorHistoryService = async ({ page, limit, search, sortBy, orderBy }, req) => {
265
+//     const skip = (page - 1) * limit;
266
+
267
+//     const hospitalId = req.params.id;
268
+//     const hospital = await prisma.hospital.findFirst({
269
+//         where: {
270
+//             id: hospitalId
271
+//         }
272
+//     })
273
+//     if (!hospital) {
274
+//         throw new HttpException("Hospital not found", 404)
275
+//     }
276
+
277
+//     const where = {
278
+//         // ...SearchFilter(search, ['name', 'name_pt']),
279
+//         hospital_id: req.params.id,
280
+//         deletedAt: null
281
+//     };
282
+
283
+//     const [vendor_histories, total] = await Promise.all([
284
+//         VendorExperienceRepository.findAll({ skip, take: limit, where, orderBy: { [sortBy]: orderBy } }),
285
+//         VendorExperienceRepository.countAll(where)
286
+//     ]);
287
+
288
+//     return { vendor_histories, total };
289
+// };
290
+
291
+// exports.showVendorHistoryService = async (req) => {
292
+//     const id_hospital = req.params.id;
293
+//     const id_vendor_experience = req.params.id_vendor_experience;
294
+
295
+//     const hospital = await prisma.hospital.findFirst({
296
+//         where: {
297
+//             id: id_hospital
298
+//         }
299
+//     })
300
+//     if (!hospital) {
301
+//         throw new HttpException("Hospital not found", 404)
302
+//     }
303
+
304
+//     VendorExperienceRepository.findById(id_vendor_experience);
305
+//     if (!vendorHistory) {
306
+//         throw new HttpException("Vendor history not found", 404);
307
+//     }
308
+
309
+//     return vendorHistory;
310
+// };
311
+
312
+// exports.storeVendorHistoryService = async (validateData, req) => {
313
+//     const hospitalId = req.params.id;
314
+
315
+//     const hospital = await prisma.hospital.findFirst({
316
+//         where: {
317
+//             id: hospitalId
318
+//         }
319
+//     });
320
+//     if (!hospital) {
321
+//         throw new HttpException("Hospital not found", 404)
322
+//     }
323
+
324
+//     const vendor = await prisma.vendor.findFirst({
325
+//         where: {
326
+//             id: validateData.vendor_id
327
+//         }
328
+//     });
329
+//     if (!vendor) {
330
+//         throw new HttpException("Vendor not found", 404)
331
+//     }
332
+
333
+//     await prisma.hospital.update({
334
+//         where: { id: hospitalId },
335
+//         data: {
336
+//             simrs_type: validateData.simrs_type
337
+//         }
338
+//     });
339
+
340
+//     if (validateData.simrs_type) {
341
+//         const existingActiveVendors = await prisma.vendorHistory.findMany({
342
+//             where: {
343
+//                 hospital_id: hospitalId,
344
+//                 status: "active",
345
+//                 deletedAt: null
346
+//             }
347
+//         });
348
+
349
+//         if (existingActiveVendors.length > 0) {
350
+//             await prisma.vendorHistory.updateMany({
351
+//                 where: {
352
+//                     hospital_id: hospitalId,
353
+//                     status: "active",
354
+//                     deletedAt: null
355
+//                 },
356
+//                 data: {
357
+//                     status: "inactive"
358
+//                 }
359
+//             });
360
+//         }
361
+
362
+//         validateData.status = "active";
363
+//     }
364
+
365
+//     const payload = {
366
+//         vendor_id: validateData.vendor_id,
367
+//         vendor_impression: validateData.vendor_impression,
368
+//         status: validateData.status,
369
+//         contract_date: validateData.contract_date,
370
+//         contract_expired_date: validateData.contract_expired_date,
371
+//         hospital_id: hospitalId
372
+//     };
373
+
374
+//     VendorExperienceRepository.create(payload);
375
+//     await createLog(req, data);
376
+// };
377
+
378
+// exports.updateVendorHistoryService = async (validateData, req) => {
379
+//     const id_hospital = req.params.id;
380
+//     const id_vendor_experience = req.params.id_vendor_experience;
381
+
382
+//     const hospital = await prisma.hospital.findFirst({
383
+//         where: {
384
+//             id: id_hospital
385
+//         }
386
+//     })
387
+//     if (!hospital) {
388
+//         throw new HttpException("Hospital not found", 404)
389
+//     }
390
+
391
+//     VendorExperienceRepository.findById(id_vendor_experience);
392
+//     if (!vendorHistory) {
393
+//         throw new HttpException("Vendor history not found", 404);
394
+//     }
395
+
396
+//     if (validateData.vendor_id) {
397
+//         const existVendor = await prisma.vendor.findFirst({
398
+//             where: {
399
+//                 id: validateData.vendor_id
400
+//             }
401
+//         });
402
+//         if (!existVendor) {
403
+//             throw new HttpException("Vendor not found", 404)
404
+//         }
405
+//     }
406
+
407
+//     await prisma.hospital.update({
408
+//         where: { id: id_hospital },
409
+//         data: {
410
+//             simrs_type: validateData.simrs_type
411
+//         }
412
+//     });
413
+
414
+//     if (validateData.contract_date && validateData.contract_expired_date) {
415
+//         if (validateData.contract_date >= validateData.contract_expired_date) {
416
+//             throw new HttpException("Contract expired date must be after contract date", 400)
417
+//         }
418
+//     }
419
+
420
+//     if (validateData.status === "active") {
421
+//         await prisma.vendorHistory.updateMany({
422
+//             where: {
423
+//                 hospital_id: id_hospital,
424
+//                 status: "active",
425
+//                 deletedAt: null,
426
+//                 NOT: { id: id_vendor_experience },
427
+//             },
428
+//             data: {
429
+//                 status: "inactive",
430
+//             },
431
+//         });
432
+//     }
433
+
434
+//     const payload = {
435
+//         vendor_id: validateData.vendor_id,
436
+//         vendor_impression: validateData.vendor_impression,
437
+//         status: validateData.status,
438
+//         contract_date: validateData.contract_date ? new Date(validateData.contract_date) : vendorHistory.contract_date,
439
+//         contract_expired_date: validateData.contract_expired_date ? new Date(validateData.contract_expired_date) : vendorHistory.contract_expired_date,
440
+//     };
441
+
442
+//     VendorExperienceRepository.update(id_vendor_experience, payload);
443
+//     await updateLog(req, data);
444
+// };
445
+
446
+// exports.deleteVendorHistoryService = async (req) => {
447
+//     const id_hospital = req.params.id;
448
+//     const id_vendor_experience = req.params.id_vendor_experience;
449
+
450
+//     const hospital = await prisma.hospital.findFirst({
451
+//         where: {
452
+//             id: id_hospital
453
+//         }
454
+//     })
455
+//     if (!hospital) {
456
+//         throw new HttpException("Hospital not found", 404)
457
+//     }
458
+
459
+//     VendorExperienceRepository.findById(id_vendor_experience);
460
+//     if (!vendor) {
461
+//         throw new HttpException("Vendor history not found", 404);
462
+//     }
463
+
464
+//     VendorExperienceRepository.update(id_vendor_experience, {
465
+//         deletedAt: timeLocal.now().toDate()
466
+//     });
467
+
468
+//     await deleteLog(req, data);
469
+// };

+ 0 - 212
src/services/sales/VendorHistoryService.js

@@ -1,212 +0,0 @@
1
-const VendorHistoryRepository = require('../../repository/sales/VendorHistoryRepository.js');
2
-const HttpException = require('../../utils/HttpException.js');
3
-const prisma = require('../../prisma/PrismaClient.js');
4
-const timeLocal = require('../../utils/TimeLocal.js');
5
-const { createLog, updateLog, deleteLog } = require('../../utils/LogActivity.js');
6
-
7
-exports.getAllVendorHistoryService = async ({ page, limit, search, sortBy, orderBy }, req) => {
8
-    const skip = (page - 1) * limit;
9
-
10
-    const hospitalId = req.params.id;
11
-    const hospital = await prisma.hospital.findFirst({
12
-        where: {
13
-            id: hospitalId
14
-        }
15
-    })
16
-    if (!hospital) {
17
-        throw new HttpException("Hospital not found", 404)
18
-    }
19
-
20
-    const where = {
21
-        // ...SearchFilter(search, ['name', 'name_pt']),
22
-        hospital_id: req.params.id,
23
-        deletedAt: null
24
-    };
25
-
26
-    const [vendor_histories, total] = await Promise.all([
27
-        VendorHistoryRepository.findAll({ skip, take: limit, where, orderBy: { [sortBy]: orderBy } }),
28
-        VendorHistoryRepository.countAll(where)
29
-    ]);
30
-
31
-    return { vendor_histories, total };
32
-};
33
-
34
-exports.showVendorHistoryService = async (req) => {
35
-    const id_hospital = req.params.id;
36
-    const id_vendor_experience = req.params.id_vendor_experience;
37
-
38
-    const hospital = await prisma.hospital.findFirst({
39
-        where: {
40
-            id: id_hospital
41
-        }
42
-    })
43
-    if (!hospital) {
44
-        throw new HttpException("Hospital not found", 404)
45
-    }
46
-
47
-    const vendorHistory = await VendorHistoryRepository.findById(id_vendor_experience);
48
-    if (!vendorHistory) {
49
-        throw new HttpException("Vendor history not found", 404);
50
-    }
51
-
52
-    return vendorHistory;
53
-};
54
-
55
-exports.storeVendorHistoryService = async (validateData, req) => {
56
-    const hospitalId = req.params.id;
57
-
58
-    const hospital = await prisma.hospital.findFirst({
59
-        where: {
60
-            id: hospitalId
61
-        }
62
-    });
63
-    if (!hospital) {
64
-        throw new HttpException("Hospital not found", 404)
65
-    }
66
-
67
-    const vendor = await prisma.vendor.findFirst({
68
-        where: {
69
-            id: validateData.vendor_id
70
-        }
71
-    });
72
-    if (!vendor) {
73
-        throw new HttpException("Vendor not found", 404)
74
-    }
75
-
76
-    await prisma.hospital.update({
77
-        where: { id: hospitalId },
78
-        data: {
79
-            simrs_type: validateData.simrs_type
80
-        }
81
-    });
82
-
83
-    if (validateData.simrs_type) {
84
-        const existingActiveVendors = await prisma.vendorHistory.findMany({
85
-            where: {
86
-                hospital_id: hospitalId,
87
-                status: "active",
88
-                deletedAt: null
89
-            }
90
-        });
91
-
92
-        if (existingActiveVendors.length > 0) {
93
-            await prisma.vendorHistory.updateMany({
94
-                where: {
95
-                    hospital_id: hospitalId,
96
-                    status: "active",
97
-                    deletedAt: null
98
-                },
99
-                data: {
100
-                    status: "inactive"
101
-                }
102
-            });
103
-        }
104
-
105
-        validateData.status = "active";
106
-    }
107
-
108
-    const payload = {
109
-        vendor_id: validateData.vendor_id,
110
-        vendor_impression: validateData.vendor_impression,
111
-        status: validateData.status,
112
-        contract_date: validateData.contract_date,
113
-        contract_expired_date: validateData.contract_expired_date,
114
-        hospital_id: hospitalId
115
-    };
116
-
117
-    const data = await VendorHistoryRepository.create(payload);
118
-    await createLog(req, data);
119
-};
120
-
121
-exports.updateVendorHistoryService = async (validateData, req) => {
122
-    const id_hospital = req.params.id;
123
-    const id_vendor_experience = req.params.id_vendor_experience;
124
-
125
-    const hospital = await prisma.hospital.findFirst({
126
-        where: {
127
-            id: id_hospital
128
-        }
129
-    })
130
-    if (!hospital) {
131
-        throw new HttpException("Hospital not found", 404)
132
-    }
133
-
134
-    const vendorHistory = await VendorHistoryRepository.findById(id_vendor_experience);
135
-    if (!vendorHistory) {
136
-        throw new HttpException("Vendor history not found", 404);
137
-    }
138
-
139
-    if (validateData.vendor_id) {
140
-        const existVendor = await prisma.vendor.findFirst({
141
-            where: {
142
-                id: validateData.vendor_id
143
-            }
144
-        });
145
-        if (!existVendor) {
146
-            throw new HttpException("Vendor not found", 404)
147
-        }
148
-    }
149
-
150
-    await prisma.hospital.update({
151
-        where: { id: id_hospital },
152
-        data: {
153
-            simrs_type: validateData.simrs_type
154
-        }
155
-    });
156
-
157
-    if (validateData.contract_date && validateData.contract_expired_date) {
158
-        if (validateData.contract_date >= validateData.contract_expired_date) {
159
-            throw new HttpException("Contract expired date must be after contract date", 400)
160
-        }
161
-    }
162
-
163
-    if (validateData.status === "active") {
164
-        await prisma.vendorHistory.updateMany({
165
-            where: {
166
-                hospital_id: id_hospital,
167
-                status: "active",
168
-                deletedAt: null,
169
-                NOT: { id: id_vendor_experience },
170
-            },
171
-            data: {
172
-                status: "inactive",
173
-            },
174
-        });
175
-    }
176
-
177
-    const payload = {
178
-        vendor_id: validateData.vendor_id,
179
-        vendor_impression: validateData.vendor_impression,
180
-        status: validateData.status,
181
-        contract_date: validateData.contract_date ? new Date(validateData.contract_date) : vendorHistory.contract_date,
182
-        contract_expired_date: validateData.contract_expired_date ? new Date(validateData.contract_expired_date) : vendorHistory.contract_expired_date,
183
-    };
184
-
185
-    const data = await VendorHistoryRepository.update(id_vendor_experience, payload);
186
-    await updateLog(req, data);
187
-};
188
-
189
-exports.deleteVendorHistoryService = async (req) => {
190
-    const id_hospital = req.params.id;
191
-    const id_vendor_experience = req.params.id_vendor_experience;
192
-
193
-    const hospital = await prisma.hospital.findFirst({
194
-        where: {
195
-            id: id_hospital
196
-        }
197
-    })
198
-    if (!hospital) {
199
-        throw new HttpException("Hospital not found", 404)
200
-    }
201
-
202
-    const vendor = await VendorHistoryRepository.findById(id_vendor_experience);
203
-    if (!vendor) {
204
-        throw new HttpException("Vendor history not found", 404);
205
-    }
206
-
207
-    const data = await VendorHistoryRepository.update(id_vendor_experience, {
208
-        deletedAt: timeLocal.now().toDate()
209
-    });
210
-
211
-    await deleteLog(req, data);
212
-};

+ 27 - 0
src/validators/sales/vendor_experience/VendorExperienceValidators.js

@@ -0,0 +1,27 @@
1
+exports.validateStoreVendorHistoryRequest = (body) => {
2
+    const { simrs_type, vendor_id, status, contract_start_date, contract_expired_date, contract_value_min, contract_value_max, positive_notes, negative_notes } = body;
3
+
4
+    const errors = {};
5
+
6
+    if (!simrs_type || simrs_type.trim() === '') {
7
+        errors.simrs_type = ['simrs type is required'];
8
+    }
9
+
10
+    if (!status || status.trim() === '') {
11
+        errors.status = ['Status is required'];
12
+    }
13
+
14
+    if (Object.keys(errors).length > 0) {
15
+        throw new HttpException(errors, 422);
16
+    }
17
+
18
+    return { simrs_type, vendor_id, status, contract_start_date, contract_expired_date, contract_value_min, contract_value_max, positive_notes, negative_notes };
19
+}
20
+
21
+exports.validateUpdateVendorHistoryRequest = (body) => {
22
+    const { simrs_type, vendor_id, status, contract_start_date, contract_expired_date, contract_value_min, contract_value_max, positive_notes, negative_notes } = body;
23
+
24
+    return {
25
+        simrs_type, vendor_id, status, contract_start_date, contract_expired_date, contract_value_min, contract_value_max, positive_notes, negative_notes
26
+    };
27
+}

+ 0 - 95
src/validators/sales/vendor_history/VendorHistoriValidators.js

@@ -1,95 +0,0 @@
1
-const HttpException = require('../../../utils/HttpException.js');
2
-
3
-exports.validateStoreVendorHistoryRequest = (body) => {
4
-    const { simrs_type, vendor_id, vendor_impression, status, contract_date, contract_expired_date } = body;
5
-
6
-    const errors = {};
7
-
8
-    if (!simrs_type || simrs_type.trim() === '') {
9
-        errors.simrs_type = ['simrs type is required'];
10
-    } else if (!['vendor', 'gratis', 'in house'].includes(simrs_type.trim().toLowerCase())) {
11
-        errors.simrs_type = ['Simrs type must be either "vendor", "gratis", or "in house"'];
12
-    }
13
-
14
-    // if (!vendor_id || vendor_id.trim() === '') {
15
-    //     errors.vendor_id = ['Vendor id is required'];
16
-    // }
17
-
18
-    // if (!vendor_impression || vendor_impression.trim() === '') {
19
-    //     errors.vendor_impression = ['Vendor impression is required'];
20
-    // }
21
-
22
-    if (!['active', 'inactive'].includes(status.trim().toLowerCase())) {
23
-        errors.status = ['Status must be either "active" or "inactive"'];
24
-    }
25
-
26
-    // if (!status || status.trim() === '') {
27
-    //     errors.status = ['Status is required'];
28
-    // } else if (!['active', 'inactive'].includes(status.trim().toLowerCase())) {
29
-    //     errors.status = ['Status must be either "active" or "inactive"'];
30
-    // }
31
-
32
-    if (contract_date !== null && contract_date !== '' && isNaN(Date.parse(contract_date))) {
33
-        errors.contract_date = ['Contract date must be a valid date'];
34
-    }
35
-
36
-
37
-    // if (!contract_date || contract_date.trim() === '') {
38
-    //     errors.contract_date = ['Contract date is required'];
39
-    // } else if (isNaN(Date.parse(contract_date))) {
40
-    //     errors.contract_date = ['Contract date must be a valid date'];
41
-    // }
42
-
43
-    if (contract_expired_date !== null && contract_expired_date !== '' && isNaN(Date.parse(contract_expired_date))) {
44
-        errors.contract_expired_date = ['Contract expired date must be a valid date'];
45
-    }
46
-
47
-    // if (!contract_expired_date || contract_expired_date.trim() === '') {
48
-    //     errors.contract_expired_date = ['Contract expired date is required'];
49
-    // } else if (isNaN(Date.parse(contract_expired_date))) {
50
-    //     errors.contract_expired_date = ['Contract expired date must be a valid date'];
51
-    // }
52
-
53
-    if (
54
-        !errors.contract_date &&
55
-        !errors.contract_expired_date &&
56
-        new Date(contract_expired_date) <= new Date(contract_date)
57
-    ) {
58
-        errors.contract_expired_date = ['Contract expired date must be after contract date'];
59
-    }
60
-
61
-    if (Object.keys(errors).length > 0) {
62
-        throw new HttpException(errors, 422);
63
-    }
64
-
65
-    return {
66
-        simrs_type: simrs_type.trim(),
67
-        vendor_id: vendor_id ? vendor_id.trim() : null,
68
-        vendor_impression: vendor_impression ? vendor_impression.trim() : null,
69
-        status: status.trim().toLowerCase(),
70
-        contract_date: contract_date ? new Date(contract_date) : null,
71
-        contract_expired_date: contract_expired_date ? new Date(contract_expired_date) : null,
72
-    };
73
-};
74
-
75
-exports.validateUpdateVendorHistoryRequest = (body) => {
76
-    const { simrs_type, vendor_id, vendor_impression, status, contract_date, contract_expired_date } = body;
77
-
78
-    if (simrs_type !== undefined && simrs_type !== null && simrs_type.trim() !== '') {
79
-        const allowedTypes = ['vendor', 'gratis', 'in house'];
80
-        const simrsTypeValue = simrs_type.trim().toLowerCase();
81
-
82
-        if (!allowedTypes.includes(simrsTypeValue)) {
83
-            throw new HttpException('Simrs type must be either "vendor", "gratis", or "in house"', 422);
84
-        }
85
-    }
86
-
87
-    return {
88
-        simrs_type,
89
-        vendor_id,
90
-        vendor_impression,
91
-        status,
92
-        contract_date,
93
-        contract_expired_date
94
-    };
95
-}