@provis/provis-common-be-module 2.6.56 → 2.6.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/class/main.repository.js +4 -4
- package/dist/constants/bankAccount.d.ts +8 -0
- package/dist/constants/bankAccount.js +54 -0
- package/dist/constants/claim/general.js +1 -1
- package/dist/constants/claim/kalog.js +1 -1
- package/dist/constants/claim/loket.js +40 -40
- package/dist/constants/claim/motorVehicle.js +1 -1
- package/dist/constants/claim/travel.js +1 -1
- package/dist/constants/config.js +2 -2
- package/dist/constants/product/coretax.d.ts +12 -0
- package/dist/constants/product/coretax.js +14 -0
- package/dist/constants/product/mv.d.ts +30 -0
- package/dist/constants/product/mv.js +158 -0
- package/dist/constants/product/property/occupation.d.ts +5 -0
- package/dist/constants/product/property/occupation.js +1725 -0
- package/dist/constants/product/property/property.js +7 -7
- package/dist/constants/product.d.ts +1 -0
- package/dist/constants/product.js +18 -12
- package/dist/constants/source.js +1 -1
- package/dist/helpers/alphaNumericCleansing.js +1 -1
- package/dist/helpers/amountDescription.js +1 -1
- package/dist/helpers/axiosGet.js +1 -1
- package/dist/helpers/axiosPost.js +1 -1
- package/dist/helpers/axiosPut.js +1 -1
- package/dist/helpers/calculateByType.js +1 -1
- package/dist/helpers/calculateForNullable.js +6 -6
- package/dist/helpers/getHeaderUser.js +4 -4
- package/dist/helpers/loop.js +2 -2
- package/dist/helpers/loopBackward.js +2 -2
- package/dist/helpers/readExcel.d.ts +2 -0
- package/package.json +1 -1
- package/docs/search-conditions.md +0 -218
|
@@ -36,7 +36,7 @@ const additionalCoverage = [
|
|
|
36
36
|
{
|
|
37
37
|
code: 'FLEXAS',
|
|
38
38
|
desc: {
|
|
39
|
-
en: 'Fire, Lightning, Explosion, Aircraft
|
|
39
|
+
en: 'Fire, Lightning, Explosion, Impact of Aircraft and Smoke',
|
|
40
40
|
id: 'Kebakaran, Petir, Ledakan, Kejatuhan Pesawat Terbang, dan Asap',
|
|
41
41
|
},
|
|
42
42
|
insuredPerils: {
|
|
@@ -61,8 +61,8 @@ const additionalCoverage = [
|
|
|
61
61
|
{
|
|
62
62
|
code: 'RSMDCC',
|
|
63
63
|
desc: {
|
|
64
|
-
en: '
|
|
65
|
-
id: '
|
|
64
|
+
en: 'Riot, Strike, Malicious Damage, and Civil Commotion & Others',
|
|
65
|
+
id: 'Kerusuhan, Pemogokan, Penghalangan Bekerja, Perbuatan Jahat, dan Huru-hara',
|
|
66
66
|
},
|
|
67
67
|
insuredPerils: {
|
|
68
68
|
true: {
|
|
@@ -89,8 +89,8 @@ const additionalCoverage = [
|
|
|
89
89
|
{
|
|
90
90
|
code: 'TSFWD',
|
|
91
91
|
desc: {
|
|
92
|
-
en: '
|
|
93
|
-
id: '
|
|
92
|
+
en: 'Typhoon, Storm, Flood, Water Damage',
|
|
93
|
+
id: 'Topan, Badai, Banjir, dan Kerusakan Akibat Air',
|
|
94
94
|
},
|
|
95
95
|
insuredPerils: {
|
|
96
96
|
true: {
|
|
@@ -117,8 +117,8 @@ const additionalCoverage = [
|
|
|
117
117
|
{
|
|
118
118
|
code: 'EQ',
|
|
119
119
|
desc: {
|
|
120
|
-
en: 'Earthquake, Volcanic Eruption
|
|
121
|
-
id: 'Gempa Bumi, Letusan Gunung Berapi, Tsunami',
|
|
120
|
+
en: 'Earthquake, Volcanic Eruption and Tsunami',
|
|
121
|
+
id: 'Gempa Bumi, Letusan Gunung Berapi, dan Tsunami',
|
|
122
122
|
},
|
|
123
123
|
insuredPerils: {
|
|
124
124
|
true: {
|
|
@@ -42,6 +42,7 @@ declare const product: {
|
|
|
42
42
|
PRODUCT_CODE_SURETY_BOND: string;
|
|
43
43
|
PRODUCT_CODE_ERECTION_ALL_RISK: string;
|
|
44
44
|
PRODUCT_CODE_PA_SOGO_ELI_DAYIN: string;
|
|
45
|
+
PRODUCT_CODE_PRODUCT_LIABILITY: string;
|
|
45
46
|
PRODUCT_POLISMALL_CARGO_MERATUS: string;
|
|
46
47
|
PRODUCT_POLISMALL_CARGO: string;
|
|
47
48
|
PRODUCT_CODE_EXIM: string;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const occupation_simple_1 = require("./product/property/occupation-simple");
|
|
4
4
|
const product = {
|
|
5
|
-
LIST: {},
|
|
6
|
-
MANUAL_LIST: [],
|
|
5
|
+
LIST: {},
|
|
6
|
+
MANUAL_LIST: [],
|
|
7
7
|
CARGO_BY_SYSTEM_LIST: [],
|
|
8
8
|
PRODUCT_CODE_PROPERTY_ALL_RISK: 'polismall-property-allrisk',
|
|
9
9
|
PRODUCT_CODE_EARTHQUAKE: 'polismall-earthquake',
|
|
@@ -45,6 +45,7 @@ const product = {
|
|
|
45
45
|
PRODUCT_CODE_SURETY_BOND: 'polismall-surety-bond',
|
|
46
46
|
PRODUCT_CODE_ERECTION_ALL_RISK: 'polismall-erection-all-risk',
|
|
47
47
|
PRODUCT_CODE_PA_SOGO_ELI_DAYIN: 'polismall-eli',
|
|
48
|
+
PRODUCT_CODE_PRODUCT_LIABILITY: 'polismall-product-liability',
|
|
48
49
|
// CARGO
|
|
49
50
|
PRODUCT_POLISMALL_CARGO_MERATUS: 'polismall-cargo-meratus-paliside',
|
|
50
51
|
PRODUCT_POLISMALL_CARGO: 'polismall-cargo',
|
|
@@ -52,17 +53,17 @@ const product = {
|
|
|
52
53
|
PRODUCT_CODE_CARGO_BUNDLE: 'polismall-cargo-bundle',
|
|
53
54
|
PRODUCT_CODE_MERIMEN_CARGO: 'polismall-merimen-cargo',
|
|
54
55
|
PRODUCT_CODE_CARGO_TEMAS: 'polismall-cargo-temas',
|
|
55
|
-
PRODUCT_CODE_CARGO_SINGLE_SHIPMENT: 'polismall-cargo-single-shipment',
|
|
56
|
+
PRODUCT_CODE_CARGO_SINGLE_SHIPMENT: 'polismall-cargo-single-shipment',
|
|
56
57
|
// OTTO
|
|
57
|
-
PRODUCT_CODE_OTTO_CI: 'polismall-otto-critical-illness',
|
|
58
|
-
PRODUCT_CODE_OTTO_FLEXAS: 'polismall-otto-flexas',
|
|
59
|
-
PRODUCT_CODE_OTTO_CRACK_SCREEN: 'polismall-otto-crack',
|
|
60
|
-
PRODUCT_CODE_OTTO_AUM_GP: 'polismall-otto-aum-gp',
|
|
61
|
-
PRODUCT_CODE_OTTO_AUM_PLN: 'polismall-otto-aum-pln',
|
|
62
|
-
PRODUCT_CODE_OTTO_AUM_PDAM: 'polismall-otto-aum-pdam',
|
|
63
|
-
PRODUCT_CODE_OTTO_AUM_SB: 'polismall-otto-aum-sb',
|
|
64
|
-
PRODUCT_CODE_OTTO_AUM_FB: 'polismall-otto-aum-fb',
|
|
65
|
-
PRODUCT_CODE_OTTO_AUM_FBK: 'polismall-otto-aum-fbk',
|
|
58
|
+
PRODUCT_CODE_OTTO_CI: 'polismall-otto-critical-illness',
|
|
59
|
+
PRODUCT_CODE_OTTO_FLEXAS: 'polismall-otto-flexas',
|
|
60
|
+
PRODUCT_CODE_OTTO_CRACK_SCREEN: 'polismall-otto-crack',
|
|
61
|
+
PRODUCT_CODE_OTTO_AUM_GP: 'polismall-otto-aum-gp',
|
|
62
|
+
PRODUCT_CODE_OTTO_AUM_PLN: 'polismall-otto-aum-pln',
|
|
63
|
+
PRODUCT_CODE_OTTO_AUM_PDAM: 'polismall-otto-aum-pdam',
|
|
64
|
+
PRODUCT_CODE_OTTO_AUM_SB: 'polismall-otto-aum-sb',
|
|
65
|
+
PRODUCT_CODE_OTTO_AUM_FB: 'polismall-otto-aum-fb',
|
|
66
|
+
PRODUCT_CODE_OTTO_AUM_FBK: 'polismall-otto-aum-fbk',
|
|
66
67
|
// BDKI
|
|
67
68
|
PRODUCT_CODE_BDKI_MOTOR: 'polismall-bdki-motor',
|
|
68
69
|
PRODUCT_CODE_BDKI_RUMAH: 'polismall-bdki-rumah',
|
|
@@ -345,6 +346,10 @@ product.LIST = {
|
|
|
345
346
|
value: product.PRODUCT_CODE_FINE_ART_COLLECTION,
|
|
346
347
|
name: "Fine Art and Collections Insurance",
|
|
347
348
|
},
|
|
349
|
+
[product.PRODUCT_CODE_PRODUCT_LIABILITY]: {
|
|
350
|
+
value: product.PRODUCT_CODE_PRODUCT_LIABILITY,
|
|
351
|
+
name: "Product Liability",
|
|
352
|
+
},
|
|
348
353
|
};
|
|
349
354
|
product.MANUAL_LIST = [
|
|
350
355
|
product.LIST[product.PRODUCT_POLISMALL_CARGO_MERATUS],
|
|
@@ -389,6 +394,7 @@ product.MANUAL_LIST = [
|
|
|
389
394
|
product.LIST[product.PRODUCT_CODE_PA_SOGO_ELI_DAYIN],
|
|
390
395
|
product.LIST[product.PRODUCT_CODE_CREDIT_DEFAULT],
|
|
391
396
|
product.LIST[product.PRODUCT_CODE_FINE_ART_COLLECTION],
|
|
397
|
+
product.LIST[product.PRODUCT_CODE_PRODUCT_LIABILITY],
|
|
392
398
|
];
|
|
393
399
|
product.CARGO_BY_SYSTEM_LIST = [
|
|
394
400
|
product.LIST[product.PRODUCT_POLISMALL_CARGO_MERATUS],
|
package/dist/constants/source.js
CHANGED
|
@@ -6,7 +6,7 @@ const source = {
|
|
|
6
6
|
SOURCE_TANTO: 'TANTO',
|
|
7
7
|
SOURCE_MERATUS_PALISIDE: 'MERATUS-PALISIDE',
|
|
8
8
|
SOURCE_TEMAS: 'TEMAS',
|
|
9
|
-
SOURCE_DOMESTIK: 'DOMESTIK',
|
|
9
|
+
SOURCE_DOMESTIK: 'DOMESTIK',
|
|
10
10
|
SOURCE_YUDHA_EXCEL: 'YUDHA',
|
|
11
11
|
SOURCE_EXIM: 'EXIM',
|
|
12
12
|
SOURCE_UPLOAD_BUNDLE: 'UPLOAD-BUNDLE',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = alphaNumericCleansing;
|
|
4
3
|
function alphaNumericCleansing(text) {
|
|
5
4
|
if (typeof text !== 'string')
|
|
6
5
|
return '';
|
|
@@ -8,3 +7,4 @@ function alphaNumericCleansing(text) {
|
|
|
8
7
|
.toLowerCase()
|
|
9
8
|
.replace(/[^a-z0-9]/g, '');
|
|
10
9
|
}
|
|
10
|
+
exports.default = alphaNumericCleansing;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = terbilang;
|
|
4
3
|
function terbilang(value) {
|
|
5
4
|
const satuan = ['', 'satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'sembilan'];
|
|
6
5
|
const belasan = ['sepuluh', 'sebelas', 'dua belas', 'tiga belas', 'empat belas', 'lima belas', 'enam belas', 'tujuh belas', 'delapan belas', 'sembilan belas'];
|
|
@@ -42,3 +41,4 @@ function terbilang(value) {
|
|
|
42
41
|
// Menghilangkan spasi yang double
|
|
43
42
|
return result.replace(/\s+/g, ' ').trim();
|
|
44
43
|
}
|
|
44
|
+
exports.default = terbilang;
|
package/dist/helpers/axiosGet.js
CHANGED
|
@@ -13,7 +13,7 @@ const axios_1 = require("axios");
|
|
|
13
13
|
const generateRelationId_1 = require("./generateRelationId");
|
|
14
14
|
const getCurrentDate_1 = require("./getCurrentDate");
|
|
15
15
|
const constants_1 = require("../constants");
|
|
16
|
-
exports.default = (
|
|
16
|
+
exports.default = ({ url, headers, params, callback, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
return yield axios_1.default.get(url, {
|
|
18
18
|
params,
|
|
19
19
|
headers: Object.assign({ 'Content-Type': 'application/json', 'X-Correlation-Id': (0, generateRelationId_1.default)(24), 'X-Transmission-Date-Time': (0, getCurrentDate_1.default)() }, headers),
|
|
@@ -13,7 +13,7 @@ const axios_1 = require("axios");
|
|
|
13
13
|
const generateRelationId_1 = require("./generateRelationId");
|
|
14
14
|
const getCurrentDate_1 = require("./getCurrentDate");
|
|
15
15
|
const constants_1 = require("../constants");
|
|
16
|
-
exports.default = (
|
|
16
|
+
exports.default = ({ url, headers, body, callback, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
return yield axios_1.default.post(url, body, {
|
|
18
18
|
headers: Object.assign({ 'Content-Type': 'application/json', 'X-Correlation-Id': (0, generateRelationId_1.default)(24), 'X-Transmission-Date-Time': (0, getCurrentDate_1.default)() }, headers),
|
|
19
19
|
}).then((result) => __awaiter(void 0, void 0, void 0, function* () {
|
package/dist/helpers/axiosPut.js
CHANGED
|
@@ -13,7 +13,7 @@ const axios_1 = require("axios");
|
|
|
13
13
|
const constants_1 = require("../constants");
|
|
14
14
|
const generateRelationId_1 = require("./generateRelationId");
|
|
15
15
|
const getCurrentDate_1 = require("./getCurrentDate");
|
|
16
|
-
exports.default = (
|
|
16
|
+
exports.default = ({ url, headers, body, callback, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
17
|
return yield axios_1.default.put(url, body, {
|
|
18
18
|
headers: Object.assign({ 'Content-Type': 'application/json', 'X-Correlation-Id': (0, generateRelationId_1.default)(24), 'X-Transmission-Date-Time': (0, getCurrentDate_1.default)() }, headers),
|
|
19
19
|
}).then((result) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = default_1;
|
|
4
3
|
const brokerage_1 = require("../constants/brokerage");
|
|
5
4
|
function default_1(request) {
|
|
6
5
|
try {
|
|
@@ -17,3 +16,4 @@ function default_1(request) {
|
|
|
17
16
|
return null;
|
|
18
17
|
}
|
|
19
18
|
}
|
|
19
|
+
exports.default = default_1;
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.minusN = exports.sumN = void 0;
|
|
4
|
-
exports.sum = sum;
|
|
5
|
-
exports.minus = minus;
|
|
6
|
-
exports.multiple = multiple;
|
|
7
|
-
exports.divide = divide;
|
|
8
|
-
exports.roundTo = roundTo;
|
|
3
|
+
exports.roundTo = exports.minusN = exports.sumN = exports.divide = exports.multiple = exports.minus = exports.sum = void 0;
|
|
9
4
|
function sum(a, b) {
|
|
10
5
|
try {
|
|
11
6
|
if (a == null && b == null)
|
|
@@ -16,6 +11,7 @@ function sum(a, b) {
|
|
|
16
11
|
return null;
|
|
17
12
|
}
|
|
18
13
|
}
|
|
14
|
+
exports.sum = sum;
|
|
19
15
|
function minus(a, b) {
|
|
20
16
|
try {
|
|
21
17
|
if (a == null && b == null)
|
|
@@ -26,6 +22,7 @@ function minus(a, b) {
|
|
|
26
22
|
return null;
|
|
27
23
|
}
|
|
28
24
|
}
|
|
25
|
+
exports.minus = minus;
|
|
29
26
|
function multiple(a, b) {
|
|
30
27
|
try {
|
|
31
28
|
if (a == null && b == null)
|
|
@@ -36,6 +33,7 @@ function multiple(a, b) {
|
|
|
36
33
|
return null;
|
|
37
34
|
}
|
|
38
35
|
}
|
|
36
|
+
exports.multiple = multiple;
|
|
39
37
|
function roundTo(num, precision = 2) {
|
|
40
38
|
try {
|
|
41
39
|
if (num == null && precision == null)
|
|
@@ -47,6 +45,7 @@ function roundTo(num, precision = 2) {
|
|
|
47
45
|
return null;
|
|
48
46
|
}
|
|
49
47
|
}
|
|
48
|
+
exports.roundTo = roundTo;
|
|
50
49
|
function divide(a, b) {
|
|
51
50
|
try {
|
|
52
51
|
if (a == null && b == null)
|
|
@@ -59,6 +58,7 @@ function divide(a, b) {
|
|
|
59
58
|
return null;
|
|
60
59
|
}
|
|
61
60
|
}
|
|
61
|
+
exports.divide = divide;
|
|
62
62
|
const sumN = (...numbers) => {
|
|
63
63
|
let result = null;
|
|
64
64
|
numbers.forEach(each => {
|
|
@@ -5,10 +5,10 @@ exports.default = (req, { isUserCodeMandatory = true } = {}) => {
|
|
|
5
5
|
if (!userCode && isUserCodeMandatory)
|
|
6
6
|
throw new Error('Usercode is not found');
|
|
7
7
|
return {
|
|
8
|
-
userCode: req.headers['x-user'] || req.headers['userCode'],
|
|
9
|
-
username: req.headers['x-username'] || req.headers['username'],
|
|
10
|
-
userEmail: req.headers['x-useremail'] || req.headers['x-user-email'] || req.headers['userEmail'],
|
|
11
|
-
isAdmin: req.headers['x-admin'] || req.headers['isAdmin'],
|
|
8
|
+
userCode: req.headers['x-user'] || req.headers['userCode'],
|
|
9
|
+
username: req.headers['x-username'] || req.headers['username'],
|
|
10
|
+
userEmail: req.headers['x-useremail'] || req.headers['x-user-email'] || req.headers['userEmail'],
|
|
11
|
+
isAdmin: req.headers['x-admin'] || req.headers['isAdmin'],
|
|
12
12
|
isPublic: req.headers['x-public'], //x-public isi 1/undefined -> jika 1 berarti akses public
|
|
13
13
|
};
|
|
14
14
|
};
|
package/dist/helpers/loop.js
CHANGED
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
function loop(
|
|
13
|
-
return __awaiter(this,
|
|
12
|
+
function loop(list, callback, result = []) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
14
|
if (list && list.length > 0) {
|
|
15
15
|
const [head, ...tail] = list;
|
|
16
16
|
return loop(tail, callback, [yield callback(head), ...result]);
|
|
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
function loop(
|
|
13
|
-
return __awaiter(this,
|
|
12
|
+
function loop(list, callback, result = []) {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
14
|
if (list && list.length > 0) {
|
|
15
15
|
const [head, ...tail] = list;
|
|
16
16
|
return loop(tail, callback, [...result, yield callback(head)]);
|
package/package.json
CHANGED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
# Search Conditions — `findAllAndCount` / `summaryField`
|
|
2
|
-
|
|
3
|
-
Panduan memakai filter pada `MainRepository` (`src/class/main.repository.ts`).
|
|
4
|
-
|
|
5
|
-
Semua method query (`findAllAndCount`, `summaryField`) menerima opsi berikut:
|
|
6
|
-
|
|
7
|
-
| Field | Tipe | Penggabungan |
|
|
8
|
-
| ------------------- | ----------------------------------------- | ------------------------------------- |
|
|
9
|
-
| `search` | `ISearchQuery[]` | semua di-**AND** (filter wajib) |
|
|
10
|
-
| `additionalSearchOr`| `(ISearchQuery[] \| ISearchOrGroup)[]` | antar-grup **AND**, isi grup **OR** |
|
|
11
|
-
| `relations` | `IMultiJoin[]` | join + kondisi |
|
|
12
|
-
| `subqueryIns` | `ISubqueryIn[]` | masing-masing di-**AND** ke query |
|
|
13
|
-
|
|
14
|
-
Bentuk `ISearchQuery`:
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
interface ISearchQuery {
|
|
18
|
-
query: string; // fragmen SQL, mis. 'status = :status' atau 'status IN (:...statuses)'
|
|
19
|
-
key: string; // nama parameter
|
|
20
|
-
value: string | number | boolean | Date;
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## 1. `search` — filter wajib (AND)
|
|
27
|
-
|
|
28
|
-
```ts
|
|
29
|
-
search: [
|
|
30
|
-
{ query: 'companyId = :companyId', key: 'companyId', value: 10 },
|
|
31
|
-
{ query: 'isDeleted = :isDeleted', key: 'isDeleted', value: false },
|
|
32
|
-
]
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
```sql
|
|
36
|
-
WHERE model.companyId = :companyId AND model.isDeleted = :isDeleted
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 2. `additionalSearchOr` — grup OR
|
|
42
|
-
|
|
43
|
-
Tiap **grup** di-AND-kan satu sama lain; **anggota dalam satu grup** di-OR-kan. Berguna untuk pencarian kata kunci di beberapa kolom.
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
additionalSearchOr: [
|
|
47
|
-
[
|
|
48
|
-
{ query: 'policyNumber ILIKE :kw', key: 'kw', value: '%123%' },
|
|
49
|
-
{ query: 'certificateNumber ILIKE :kw2', key: 'kw2', value: '%123%' },
|
|
50
|
-
],
|
|
51
|
-
]
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
```sql
|
|
55
|
-
AND (model.policyNumber ILIKE :kw OR model.certificateNumber ILIKE :kw2)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
> Catatan: pakai key parameter yang **unik** per kondisi agar tidak saling menimpa.
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## 3. `subqueryIns` — `column IN (subquery)`
|
|
63
|
-
|
|
64
|
-
Mencocokkan kolom table utama terhadap hasil sebuah subquery. Tiap entri di-**AND**-kan ke query utama.
|
|
65
|
-
|
|
66
|
-
Bentuk `ISubqueryIn`:
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
interface ISubqueryIn {
|
|
70
|
-
column: string; // kolom pada table utama (sisi kiri IN)
|
|
71
|
-
subqueryTable: string; // table sumber subquery
|
|
72
|
-
subqueryAlias?: string; // alias table subquery
|
|
73
|
-
subquerySelectColumn: string; // kolom yang di-SELECT subquery (sisi kanan IN)
|
|
74
|
-
searchs?: ISearchQuery[]; // kondisi di dalam subquery, di-AND
|
|
75
|
-
additionalSearchOr?: ISearchQuery[][]; // kondisi OR di dalam subquery
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Contoh — kondisi AND di dalam subquery
|
|
80
|
-
|
|
81
|
-
```ts
|
|
82
|
-
subqueryIns: [{
|
|
83
|
-
column: 'id',
|
|
84
|
-
subqueryTable: 'declarationAttachment',
|
|
85
|
-
subqueryAlias: 'da',
|
|
86
|
-
subquerySelectColumn: 'declarationId',
|
|
87
|
-
searchs: [
|
|
88
|
-
{ query: 'containerNo = :cn', key: 'cn', value: 'ABC123' },
|
|
89
|
-
{ query: 'isActive = :ia', key: 'ia', value: true },
|
|
90
|
-
],
|
|
91
|
-
}]
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
```sql
|
|
95
|
-
AND model.id IN (
|
|
96
|
-
SELECT da.declarationId FROM declarationAttachment da
|
|
97
|
-
WHERE da.containerNo = :cn AND da.isActive = :ia
|
|
98
|
-
)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Contoh — kondisi OR di dalam subquery
|
|
102
|
-
|
|
103
|
-
Pakai `additionalSearchOr` (satu grup → anggotanya OR):
|
|
104
|
-
|
|
105
|
-
```ts
|
|
106
|
-
subqueryIns: [{
|
|
107
|
-
column: 'id',
|
|
108
|
-
subqueryTable: 'declarationAttachment',
|
|
109
|
-
subqueryAlias: 'da',
|
|
110
|
-
subquerySelectColumn: 'declarationId',
|
|
111
|
-
additionalSearchOr: [[
|
|
112
|
-
{ query: 'containerNo LIKE :cn', key: 'cn', value: '%X%' },
|
|
113
|
-
{ query: 'sealNo LIKE :sn', key: 'sn', value: '%X%' },
|
|
114
|
-
]],
|
|
115
|
-
}]
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
```sql
|
|
119
|
-
AND model.id IN (
|
|
120
|
-
SELECT da.declarationId FROM declarationAttachment da
|
|
121
|
-
WHERE (da.containerNo LIKE :cn OR da.sealNo LIKE :sn)
|
|
122
|
-
)
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## 4. Subquery sebagai bagian dari grup OR (`ISearchOrGroup`)
|
|
128
|
-
|
|
129
|
-
Kalau pencarian `IN (subquery)` harus di-**OR**-kan bersama field text search (mis. "cocok kalau field declaration cocok **ATAU** attachment-nya cocok"), masukkan subquery ke dalam grup `additionalSearchOr` berbentuk objek:
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
interface ISearchOrGroup {
|
|
133
|
-
searchs?: ISearchQuery[]; // kondisi field di table utama
|
|
134
|
-
subqueryIns?: ISubqueryIn[]; // subquery IN, di-OR-kan dengan searchs
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Semua anggota grup (`searchs` + `subqueryIns`) digabung **OR** di dalam satu bracket, lalu bracket itu di-**AND**-kan ke query (jadi filter wajib tetap berlaku).
|
|
139
|
-
|
|
140
|
-
### Contoh lengkap
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
const attachmentSearchs = [
|
|
144
|
-
{ query: 'containerNo LIKE :cn', key: 'cn', value: '%X%' },
|
|
145
|
-
{ query: 'sealNo LIKE :sn', key: 'sn', value: '%X%' },
|
|
146
|
-
];
|
|
147
|
-
|
|
148
|
-
const attachmentSubquery = {
|
|
149
|
-
column: 'id',
|
|
150
|
-
subqueryTable: 'declarationAttachment',
|
|
151
|
-
subqueryAlias: 'da',
|
|
152
|
-
subquerySelectColumn: 'declarationId',
|
|
153
|
-
additionalSearchOr: [attachmentSearchs], // (da.containerNo LIKE :cn OR da.sealNo LIKE :sn)
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
const [total, data] = await repo.findAllAndCount({
|
|
157
|
-
search: [
|
|
158
|
-
{ query: 'companyId = :companyId', key: 'companyId', value: 10 }, // filter wajib (AND)
|
|
159
|
-
],
|
|
160
|
-
additionalSearchOr: [
|
|
161
|
-
{
|
|
162
|
-
searchs: [
|
|
163
|
-
{ query: 'policyNumber ILIKE :kw', key: 'kw', value: '%X%' },
|
|
164
|
-
{ query: 'certificateNumber ILIKE :kw2', key: 'kw2', value: '%X%' },
|
|
165
|
-
],
|
|
166
|
-
subqueryIns: [attachmentSubquery],
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
});
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
```sql
|
|
173
|
-
WHERE model.companyId = :companyId -- filter wajib, AND
|
|
174
|
-
AND (
|
|
175
|
-
model.policyNumber ILIKE :kw
|
|
176
|
-
OR model.certificateNumber ILIKE :kw2
|
|
177
|
-
OR model.id IN (
|
|
178
|
-
SELECT da.declarationId FROM declarationAttachment da
|
|
179
|
-
WHERE (da.containerNo LIKE :cn OR da.sealNo LIKE :sn)
|
|
180
|
-
)
|
|
181
|
-
)
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Menyisipkan subquery ke grup `searchOr` yang sudah ada
|
|
185
|
-
|
|
186
|
-
Kalau grup OR dibangun dari `searchBracket(search.searchOr, ...)`, sisipkan subquery ke grup pertama:
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
const searchOrGroups = search.searchOr
|
|
190
|
-
? await repo.searchBracket(search.searchOr, this.searchValueDeclaration)
|
|
191
|
-
: [];
|
|
192
|
-
|
|
193
|
-
const additionalSearchOr = (() => {
|
|
194
|
-
if (attachmentSearchs.length === 0) return searchOrGroups;
|
|
195
|
-
if (searchOrGroups.length === 0) return [{ subqueryIns: [attachmentSubquery] }];
|
|
196
|
-
return searchOrGroups.map((g, i) =>
|
|
197
|
-
i === 0 ? { searchs: g, subqueryIns: [attachmentSubquery] } : g
|
|
198
|
-
);
|
|
199
|
-
})();
|
|
200
|
-
|
|
201
|
-
const [total, data] = await repo.findAllAndCount({
|
|
202
|
-
search: this.searchValueDeclaration(search, user),
|
|
203
|
-
additionalSearchOr,
|
|
204
|
-
maxCount, offset, sortBy: search.sortBy,
|
|
205
|
-
});
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## Ringkasan AND vs OR
|
|
211
|
-
|
|
212
|
-
| Mau... | Pakai |
|
|
213
|
-
| --------------------------------------------------- | ----------------------------------------------------------- |
|
|
214
|
-
| Filter wajib (selalu berlaku) | `search` |
|
|
215
|
-
| OR antar beberapa kolom (search box) | `additionalSearchOr: [[ ... ]]` |
|
|
216
|
-
| `col IN (subquery)`, di-AND ke query | `subqueryIns: [ ... ]` |
|
|
217
|
-
| OR **di dalam** subquery | `subqueryIns[].additionalSearchOr` |
|
|
218
|
-
| `col IN (subquery)` di-**OR** dengan field lain | grup objek `{ searchs, subqueryIns }` di `additionalSearchOr` |
|