@zauru-sdk/common 6.11.0 → 6.11.1
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.checkProviderRestrictionValue = exports.validateProviderRestrictionInput = exports.matchReceptionTypeCode = exports.isRestrictionValueAllowed = exports.resolveAllowedRestrictionValues = exports.filterActiveProviderRestrictions = exports.isRestrictionActiveOnDate = exports.restrictionHasDateRange = exports.normalizeProviderRestrictionValues = exports.isProviderRestrictionMode = exports.formatRestrictionTypeValue = exports.normalizeRestrictionValue = exports.PROVIDER_ITEM_RESTRICTIONS_TABLE_VAR = exports.PROVIDER_TYPE_RESTRICTIONS_TABLE_VAR = void 0;
|
|
3
|
+
exports.checkProviderRestrictionValue = exports.validateProviderRestrictionInput = exports.restrictionLeavesNoAllowedValues = exports.sampleDatesForRestrictionRules = exports.matchReceptionTypeCode = exports.isRestrictionValueAllowed = exports.resolveAllowedRestrictionValues = exports.filterActiveProviderRestrictions = exports.isRestrictionActiveOnDate = exports.restrictionHasDateRange = exports.normalizeProviderRestrictionValues = exports.isProviderRestrictionMode = exports.formatRestrictionTypeValue = exports.normalizeRestrictionValue = exports.PROVIDER_ITEM_RESTRICTIONS_TABLE_VAR = exports.PROVIDER_TYPE_RESTRICTIONS_TABLE_VAR = void 0;
|
|
4
4
|
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
5
5
|
exports.PROVIDER_TYPE_RESTRICTIONS_TABLE_VAR = "ctl_calidad_admin_restricciones_tipos_proveedor_web_app_table_id";
|
|
6
6
|
exports.PROVIDER_ITEM_RESTRICTIONS_TABLE_VAR = "ctl_calidad_admin_restricciones_verduras_proveedor_web_app_table_id";
|
|
@@ -119,7 +119,47 @@ const matchReceptionTypeCode = (formValue, types) => {
|
|
|
119
119
|
return wanted;
|
|
120
120
|
};
|
|
121
121
|
exports.matchReceptionTypeCode = matchReceptionTypeCode;
|
|
122
|
-
const
|
|
122
|
+
const shiftYmd = (ymd, days) => {
|
|
123
|
+
const [year, month, day] = ymd.split("-").map(Number);
|
|
124
|
+
const utc = new Date(Date.UTC(year, month - 1, day + days));
|
|
125
|
+
const nextYear = utc.getUTCFullYear();
|
|
126
|
+
const nextMonth = String(utc.getUTCMonth() + 1).padStart(2, "0");
|
|
127
|
+
const nextDay = String(utc.getUTCDate()).padStart(2, "0");
|
|
128
|
+
return `${nextYear}-${nextMonth}-${nextDay}`;
|
|
129
|
+
};
|
|
130
|
+
const sampleDatesForRestrictionRules = (rules) => {
|
|
131
|
+
const dates = new Set(["1970-01-01", "2999-12-31"]);
|
|
132
|
+
for (const rule of rules) {
|
|
133
|
+
const start = (0, exports.normalizeRestrictionValue)(rule.start_date);
|
|
134
|
+
const end = (0, exports.normalizeRestrictionValue)(rule.end_date);
|
|
135
|
+
if (DATE_RE.test(start)) {
|
|
136
|
+
dates.add(start);
|
|
137
|
+
dates.add(shiftYmd(start, -1));
|
|
138
|
+
}
|
|
139
|
+
if (DATE_RE.test(end)) {
|
|
140
|
+
dates.add(end);
|
|
141
|
+
dates.add(shiftYmd(end, 1));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return [...dates].sort();
|
|
145
|
+
};
|
|
146
|
+
exports.sampleDatesForRestrictionRules = sampleDatesForRestrictionRules;
|
|
147
|
+
const restrictionLeavesNoAllowedValues = (input) => {
|
|
148
|
+
const universe = input.universe
|
|
149
|
+
.map(exports.normalizeRestrictionValue)
|
|
150
|
+
.filter(Boolean);
|
|
151
|
+
if (universe.length === 0) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return (0, exports.sampleDatesForRestrictionRules)(input.rules ?? []).some((date) => (0, exports.resolveAllowedRestrictionValues)({
|
|
155
|
+
payeeId: input.payeeId,
|
|
156
|
+
date,
|
|
157
|
+
rules: input.rules,
|
|
158
|
+
universe,
|
|
159
|
+
}).length === 0);
|
|
160
|
+
};
|
|
161
|
+
exports.restrictionLeavesNoAllowedValues = restrictionLeavesNoAllowedValues;
|
|
162
|
+
const validateProviderRestrictionInput = (input, options) => {
|
|
123
163
|
const errors = [];
|
|
124
164
|
if (!Number(input.payee_id) || Number(input.payee_id) < 1) {
|
|
125
165
|
errors.push({ field: "payee_id", message: "Seleccione un proveedor." });
|
|
@@ -166,6 +206,35 @@ const validateProviderRestrictionInput = (input) => {
|
|
|
166
206
|
});
|
|
167
207
|
}
|
|
168
208
|
}
|
|
209
|
+
const universe = (options?.universe ?? [])
|
|
210
|
+
.map(exports.normalizeRestrictionValue)
|
|
211
|
+
.filter(Boolean);
|
|
212
|
+
if (universe.length > 0 &&
|
|
213
|
+
Number(input.payee_id) > 0 &&
|
|
214
|
+
(0, exports.isProviderRestrictionMode)(input.mode) &&
|
|
215
|
+
(0, exports.normalizeProviderRestrictionValues)(input.values).length > 0) {
|
|
216
|
+
const proposed = {
|
|
217
|
+
payee_id: Number(input.payee_id),
|
|
218
|
+
mode: input.mode,
|
|
219
|
+
values: (0, exports.normalizeProviderRestrictionValues)(input.values),
|
|
220
|
+
start_date: start,
|
|
221
|
+
end_date: end,
|
|
222
|
+
motivo: (0, exports.normalizeRestrictionValue)(input.motivo),
|
|
223
|
+
};
|
|
224
|
+
const otherRules = (options?.otherRules ?? []).filter((rule) => Number(rule.payee_id) === Number(input.payee_id) &&
|
|
225
|
+
!(0, exports.normalizeRestrictionValue)(rule.fechaEliminacion));
|
|
226
|
+
if ((0, exports.restrictionLeavesNoAllowedValues)({
|
|
227
|
+
payeeId: Number(input.payee_id),
|
|
228
|
+
rules: [...otherRules, proposed],
|
|
229
|
+
universe,
|
|
230
|
+
})) {
|
|
231
|
+
const noun = (0, exports.normalizeRestrictionValue)(options?.valueNoun) || "opciones";
|
|
232
|
+
errors.push({
|
|
233
|
+
field: "values",
|
|
234
|
+
message: `Esta regla dejaría al proveedor sin ${noun} para escoger. Debe quedar al menos uno.`,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
169
238
|
return errors;
|
|
170
239
|
};
|
|
171
240
|
exports.validateProviderRestrictionInput = validateProviderRestrictionInput;
|
|
@@ -39,7 +39,18 @@ export type ProviderRestrictionInputError = {
|
|
|
39
39
|
field: string;
|
|
40
40
|
message: string;
|
|
41
41
|
};
|
|
42
|
-
export
|
|
42
|
+
export type ValidateProviderRestrictionOptions = {
|
|
43
|
+
universe?: Array<string | number>;
|
|
44
|
+
otherRules?: ProviderRestrictionRule[];
|
|
45
|
+
valueNoun?: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const sampleDatesForRestrictionRules: (rules: Array<Pick<ProviderRestrictionRule, "start_date" | "end_date">>) => string[];
|
|
48
|
+
export declare const restrictionLeavesNoAllowedValues: (input: {
|
|
49
|
+
payeeId: number;
|
|
50
|
+
rules: ProviderRestrictionRule[] | undefined;
|
|
51
|
+
universe: Array<string | number>;
|
|
52
|
+
}) => boolean;
|
|
53
|
+
export declare const validateProviderRestrictionInput: (input: ProviderRestrictionInput, options?: ValidateProviderRestrictionOptions) => ProviderRestrictionInputError[];
|
|
43
54
|
export declare const checkProviderRestrictionValue: (input: {
|
|
44
55
|
payeeId: number;
|
|
45
56
|
date: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zauru-sdk/common",
|
|
3
|
-
"version": "6.11.
|
|
3
|
+
"version": "6.11.1",
|
|
4
4
|
"description": "Funciones de uso común en el desarrollo de webapps en Zauru",
|
|
5
5
|
"main": "./dist/esm/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"moment": "^2.30.1",
|
|
27
27
|
"moment-timezone": "^0.5.45"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "04f79cf77f767191f4be6358d9b23a3a0f1641b0"
|
|
30
30
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
isRestrictionValueAllowed,
|
|
9
9
|
matchReceptionTypeCode,
|
|
10
10
|
resolveAllowedRestrictionValues,
|
|
11
|
+
restrictionLeavesNoAllowedValues,
|
|
11
12
|
validateProviderRestrictionInput,
|
|
12
13
|
} from "./providerRestrictions.js";
|
|
13
14
|
|
|
@@ -274,4 +275,86 @@ describe("validateProviderRestrictionInput", () => {
|
|
|
274
275
|
true,
|
|
275
276
|
);
|
|
276
277
|
});
|
|
278
|
+
|
|
279
|
+
it("When exclude removes every value in the universe, it should reject it", () => {
|
|
280
|
+
const errors = validateProviderRestrictionInput(
|
|
281
|
+
{
|
|
282
|
+
payee_id: 1,
|
|
283
|
+
mode: "exclude",
|
|
284
|
+
values: ["N", "1"],
|
|
285
|
+
},
|
|
286
|
+
{ universe: ["N", "1"], valueNoun: "tipos de recepción" },
|
|
287
|
+
);
|
|
288
|
+
assert.equal(
|
|
289
|
+
errors.some((error) => error.message.includes("sin tipos de recepción")),
|
|
290
|
+
true,
|
|
291
|
+
);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("When exclude leaves at least one value, it should allow it", () => {
|
|
295
|
+
const errors = validateProviderRestrictionInput(
|
|
296
|
+
{
|
|
297
|
+
payee_id: 1,
|
|
298
|
+
mode: "exclude",
|
|
299
|
+
values: ["1"],
|
|
300
|
+
},
|
|
301
|
+
{ universe: ["N", "1"] },
|
|
302
|
+
);
|
|
303
|
+
assert.deepEqual(errors, []);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("When an overlapping exclude would empty an include, it should reject it", () => {
|
|
307
|
+
const errors = validateProviderRestrictionInput(
|
|
308
|
+
{
|
|
309
|
+
payee_id: 10,
|
|
310
|
+
mode: "exclude",
|
|
311
|
+
values: ["Normal"],
|
|
312
|
+
start_date: "2026-10-27",
|
|
313
|
+
end_date: "2026-11-02",
|
|
314
|
+
motivo: "Auditoría",
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
universe: ["Normal", "Certificado 1"],
|
|
318
|
+
otherRules: [
|
|
319
|
+
rule({
|
|
320
|
+
payee_id: 10,
|
|
321
|
+
mode: "include",
|
|
322
|
+
values: ["Normal"],
|
|
323
|
+
}),
|
|
324
|
+
],
|
|
325
|
+
},
|
|
326
|
+
);
|
|
327
|
+
assert.equal(
|
|
328
|
+
errors.some((error) => error.field === "values"),
|
|
329
|
+
true,
|
|
330
|
+
);
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
describe("restrictionLeavesNoAllowedValues", () => {
|
|
335
|
+
it("When two dated excludes only empty the overlap, it should detect that day", () => {
|
|
336
|
+
assert.equal(
|
|
337
|
+
restrictionLeavesNoAllowedValues({
|
|
338
|
+
payeeId: 3,
|
|
339
|
+
universe: ["A", "B"],
|
|
340
|
+
rules: [
|
|
341
|
+
rule({
|
|
342
|
+
payee_id: 3,
|
|
343
|
+
mode: "exclude",
|
|
344
|
+
values: ["A"],
|
|
345
|
+
start_date: "2026-10-01",
|
|
346
|
+
end_date: "2026-10-20",
|
|
347
|
+
}),
|
|
348
|
+
rule({
|
|
349
|
+
payee_id: 3,
|
|
350
|
+
mode: "exclude",
|
|
351
|
+
values: ["B"],
|
|
352
|
+
start_date: "2026-10-10",
|
|
353
|
+
end_date: "2026-10-15",
|
|
354
|
+
}),
|
|
355
|
+
],
|
|
356
|
+
}),
|
|
357
|
+
true,
|
|
358
|
+
);
|
|
359
|
+
});
|
|
277
360
|
});
|
|
@@ -196,8 +196,65 @@ export type ProviderRestrictionInputError = {
|
|
|
196
196
|
message: string;
|
|
197
197
|
};
|
|
198
198
|
|
|
199
|
+
export type ValidateProviderRestrictionOptions = {
|
|
200
|
+
universe?: Array<string | number>;
|
|
201
|
+
otherRules?: ProviderRestrictionRule[];
|
|
202
|
+
valueNoun?: string;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const shiftYmd = (ymd: string, days: number): string => {
|
|
206
|
+
const [year, month, day] = ymd.split("-").map(Number);
|
|
207
|
+
const utc = new Date(Date.UTC(year, month - 1, day + days));
|
|
208
|
+
const nextYear = utc.getUTCFullYear();
|
|
209
|
+
const nextMonth = String(utc.getUTCMonth() + 1).padStart(2, "0");
|
|
210
|
+
const nextDay = String(utc.getUTCDate()).padStart(2, "0");
|
|
211
|
+
return `${nextYear}-${nextMonth}-${nextDay}`;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export const sampleDatesForRestrictionRules = (
|
|
215
|
+
rules: Array<Pick<ProviderRestrictionRule, "start_date" | "end_date">>,
|
|
216
|
+
): string[] => {
|
|
217
|
+
const dates = new Set<string>(["1970-01-01", "2999-12-31"]);
|
|
218
|
+
for (const rule of rules) {
|
|
219
|
+
const start = normalizeRestrictionValue(rule.start_date);
|
|
220
|
+
const end = normalizeRestrictionValue(rule.end_date);
|
|
221
|
+
if (DATE_RE.test(start)) {
|
|
222
|
+
dates.add(start);
|
|
223
|
+
dates.add(shiftYmd(start, -1));
|
|
224
|
+
}
|
|
225
|
+
if (DATE_RE.test(end)) {
|
|
226
|
+
dates.add(end);
|
|
227
|
+
dates.add(shiftYmd(end, 1));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return [...dates].sort();
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
export const restrictionLeavesNoAllowedValues = (input: {
|
|
234
|
+
payeeId: number;
|
|
235
|
+
rules: ProviderRestrictionRule[] | undefined;
|
|
236
|
+
universe: Array<string | number>;
|
|
237
|
+
}): boolean => {
|
|
238
|
+
const universe = input.universe
|
|
239
|
+
.map(normalizeRestrictionValue)
|
|
240
|
+
.filter(Boolean);
|
|
241
|
+
if (universe.length === 0) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
return sampleDatesForRestrictionRules(input.rules ?? []).some(
|
|
245
|
+
(date) =>
|
|
246
|
+
resolveAllowedRestrictionValues({
|
|
247
|
+
payeeId: input.payeeId,
|
|
248
|
+
date,
|
|
249
|
+
rules: input.rules,
|
|
250
|
+
universe,
|
|
251
|
+
}).length === 0,
|
|
252
|
+
);
|
|
253
|
+
};
|
|
254
|
+
|
|
199
255
|
export const validateProviderRestrictionInput = (
|
|
200
256
|
input: ProviderRestrictionInput,
|
|
257
|
+
options?: ValidateProviderRestrictionOptions,
|
|
201
258
|
): ProviderRestrictionInputError[] => {
|
|
202
259
|
const errors: ProviderRestrictionInputError[] = [];
|
|
203
260
|
if (!Number(input.payee_id) || Number(input.payee_id) < 1) {
|
|
@@ -245,6 +302,44 @@ export const validateProviderRestrictionInput = (
|
|
|
245
302
|
}
|
|
246
303
|
}
|
|
247
304
|
|
|
305
|
+
const universe = (options?.universe ?? [])
|
|
306
|
+
.map(normalizeRestrictionValue)
|
|
307
|
+
.filter(Boolean);
|
|
308
|
+
if (
|
|
309
|
+
universe.length > 0 &&
|
|
310
|
+
Number(input.payee_id) > 0 &&
|
|
311
|
+
isProviderRestrictionMode(input.mode) &&
|
|
312
|
+
normalizeProviderRestrictionValues(input.values).length > 0
|
|
313
|
+
) {
|
|
314
|
+
const proposed: ProviderRestrictionRule = {
|
|
315
|
+
payee_id: Number(input.payee_id),
|
|
316
|
+
mode: input.mode,
|
|
317
|
+
values: normalizeProviderRestrictionValues(input.values),
|
|
318
|
+
start_date: start,
|
|
319
|
+
end_date: end,
|
|
320
|
+
motivo: normalizeRestrictionValue(input.motivo),
|
|
321
|
+
};
|
|
322
|
+
const otherRules = (options?.otherRules ?? []).filter(
|
|
323
|
+
(rule) =>
|
|
324
|
+
Number(rule.payee_id) === Number(input.payee_id) &&
|
|
325
|
+
!normalizeRestrictionValue(rule.fechaEliminacion),
|
|
326
|
+
);
|
|
327
|
+
if (
|
|
328
|
+
restrictionLeavesNoAllowedValues({
|
|
329
|
+
payeeId: Number(input.payee_id),
|
|
330
|
+
rules: [...otherRules, proposed],
|
|
331
|
+
universe,
|
|
332
|
+
})
|
|
333
|
+
) {
|
|
334
|
+
const noun =
|
|
335
|
+
normalizeRestrictionValue(options?.valueNoun) || "opciones";
|
|
336
|
+
errors.push({
|
|
337
|
+
field: "values",
|
|
338
|
+
message: `Esta regla dejaría al proveedor sin ${noun} para escoger. Debe quedar al menos uno.`,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
248
343
|
return errors;
|
|
249
344
|
};
|
|
250
345
|
|