feat: parámetros ocultos (títulos y separadores) de los reportes Crystal
This commit is contained in:
1 parent
2a29c63e7d
commit
03ccd97f99
3 files changed
+13
-1
No files matched your search
@@ -14,6 +14,7 @@ const paramSchema = z.object({
|
|||||||
label: text(120).min(1),
|
label: text(120).min(1),
|
||||||
kind: z.enum(['text', 'number', 'date', 'select', 'lookup']),
|
kind: z.enum(['text', 'number', 'date', 'select', 'lookup']),
|
||||||
required: z.boolean(),
|
required: z.boolean(),
|
||||||
|
hidden: z.boolean().optional(),
|
||||||
range: z.boolean().optional(),
|
range: z.boolean().optional(),
|
||||||
multiple: z.boolean().optional(),
|
multiple: z.boolean().optional(),
|
||||||
defaultValue: text(200).optional(),
|
defaultValue: text(200).optional(),
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ describe('paramsFromLoadCr', () => {
|
|||||||
{ name: 'Dockey@', type: 'xsd:decimal', description: 'Especificar Dockey@:', isOptionalPrompt: 'false', valueRangeKind: 'Discrete', allowMultiValue: 'false' },
|
{ name: 'Dockey@', type: 'xsd:decimal', description: 'Especificar Dockey@:', isOptionalPrompt: 'false', valueRangeKind: 'Discrete', allowMultiValue: 'false' },
|
||||||
{ name: 'BP@From OCRD', type: 'xsd:string', description: 'Socios de negocios', isOptionalPrompt: 'true', allowMultiValue: 'true', defaultValues: ['C1'] },
|
{ name: 'BP@From OCRD', type: 'xsd:string', description: 'Socios de negocios', isOptionalPrompt: 'true', allowMultiValue: 'true', defaultValues: ['C1'] },
|
||||||
{ type: 'xsd:string' },
|
{ type: 'xsd:string' },
|
||||||
|
{ name: 'Title_Items@Title', type: 'xsd:string', description: 'Artículos', isOptionalPrompt: 'false' },
|
||||||
]);
|
]);
|
||||||
expect(params).toEqual([
|
expect(params).toEqual([
|
||||||
{ name: 'PWZRunDate', type: 'xsd:date', label: 'Fecha de ejecución de pago', kind: 'date', required: false, range: true },
|
{ name: 'PWZRunDate', type: 'xsd:date', label: 'Fecha de ejecución de pago', kind: 'date', required: false, range: true },
|
||||||
{ name: 'Dockey@', type: 'xsd:decimal', label: 'Dockey@', kind: 'number', required: true },
|
{ name: 'Dockey@', type: 'xsd:decimal', label: 'Dockey@', kind: 'number', required: true },
|
||||||
{ name: 'BP@From OCRD', type: 'xsd:string', label: 'Socios de negocios', kind: 'text', required: false, multiple: true, defaultValue: 'C1' },
|
{ name: 'BP@From OCRD', type: 'xsd:string', label: 'Socios de negocios', kind: 'text', required: false, multiple: true, defaultValue: 'C1' },
|
||||||
|
{ name: 'Title_Items@Title', type: 'xsd:string', label: 'Artículos', kind: 'text', required: false, hidden: true },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -36,6 +38,10 @@ describe('exportBody', () => {
|
|||||||
expect(r.missing).toEqual(['Cliente']);
|
expect(r.missing).toEqual(['Cliente']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('los títulos del reporte no se piden ni se envían', () => {
|
||||||
|
expect(exportBody([p({ name: 'T@Title', hidden: true, required: true })], { 'T@Title': 'x' }).body).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('ignora valores de parámetros que no están matriculados', () => {
|
it('ignora valores de parámetros que no están matriculados', () => {
|
||||||
expect(exportBody([p({ name: 'A' })], { A: '1', Otro: '2' }).body.map((b) => b.name)).toEqual(['A']);
|
expect(exportBody([p({ name: 'A' })], { A: '1', Otro: '2' }).body.map((b) => b.name)).toEqual(['A']);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ export interface GatewayParam {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
/** Opciones de una lista fija (`kind = select`). */
|
/** Opciones de una lista fija (`kind = select`). */
|
||||||
options?: { value: string; label: string }[];
|
options?: { value: string; label: string }[];
|
||||||
|
/** Un título o separador del reporte (`Title_Items@Title`, `Sep_item@separator`): no se pide al usuario ni se envía. */
|
||||||
|
hidden?: boolean;
|
||||||
/** Ventana de selección (`kind = lookup`): identificador de su catálogo en la web (`socios`, `articulos`, `doc:Invoices`…). */
|
/** Ventana de selección (`kind = lookup`): identificador de su catálogo en la web (`socios`, `articulos`, `doc:Invoices`…). */
|
||||||
lookup?: string;
|
lookup?: string;
|
||||||
}
|
}
|
||||||
@@ -70,12 +72,14 @@ export function paramsFromLoadCr(resultSet: readonly CrystalParameter[]): Gatewa
|
|||||||
.map((p) => {
|
.map((p) => {
|
||||||
const type = p.type ?? 'xsd:string';
|
const type = p.type ?? 'xsd:string';
|
||||||
const first = p.defaultValues?.[0];
|
const first = p.defaultValues?.[0];
|
||||||
|
const decorative = /@(title|separator)$/i.test(p.name);
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
type,
|
type,
|
||||||
label: (p.description ?? p.name).replace(/[:\s]+$/, '').replace(/^Especificar\s+/i, '') || p.name,
|
label: (p.description ?? p.name).replace(/[:\s]+$/, '').replace(/^Especificar\s+/i, '') || p.name,
|
||||||
kind: /date/i.test(type) ? 'date' : NUMERIC.test(type) ? 'number' : 'text',
|
kind: /date/i.test(type) ? 'date' : NUMERIC.test(type) ? 'number' : 'text',
|
||||||
required: p.isOptionalPrompt !== 'true',
|
required: decorative ? false : p.isOptionalPrompt !== 'true',
|
||||||
|
...(decorative ? { hidden: true } : {}),
|
||||||
...(p.valueRangeKind === 'Range' ? { range: true } : {}),
|
...(p.valueRangeKind === 'Range' ? { range: true } : {}),
|
||||||
...(p.allowMultiValue === 'true' ? { multiple: true } : {}),
|
...(p.allowMultiValue === 'true' ? { multiple: true } : {}),
|
||||||
...(first !== undefined && first !== null && first !== '' ? { defaultValue: String(first) } : {}),
|
...(first !== undefined && first !== null && first !== '' ? { defaultValue: String(first) } : {}),
|
||||||
@@ -94,6 +98,7 @@ export function exportBody(params: readonly GatewayParam[], values: GatewayValue
|
|||||||
const body: { name: string; type: string; value: string[][] }[] = [];
|
const body: { name: string; type: string; value: string[][] }[] = [];
|
||||||
const missing: string[] = [];
|
const missing: string[] = [];
|
||||||
for (const p of params) {
|
for (const p of params) {
|
||||||
|
if (p.hidden) continue;
|
||||||
const raw = values[p.name];
|
const raw = values[p.name];
|
||||||
if (isBlank(raw)) {
|
if (isBlank(raw)) {
|
||||||
if (p.required) missing.push(p.label);
|
if (p.required) missing.push(p.label);
|
||||||
|
|||||||
Reference in new issue
Block a user