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),
|
||||
kind: z.enum(['text', 'number', 'date', 'select', 'lookup']),
|
||||
required: z.boolean(),
|
||||
hidden: z.boolean().optional(),
|
||||
range: z.boolean().optional(),
|
||||
multiple: z.boolean().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: 'BP@From OCRD', type: 'xsd:string', description: 'Socios de negocios', isOptionalPrompt: 'true', allowMultiValue: 'true', defaultValues: ['C1'] },
|
||||
{ type: 'xsd:string' },
|
||||
{ name: 'Title_Items@Title', type: 'xsd:string', description: 'Artículos', isOptionalPrompt: 'false' },
|
||||
]);
|
||||
expect(params).toEqual([
|
||||
{ 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: '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']);
|
||||
});
|
||||
|
||||
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', () => {
|
||||
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;
|
||||
/** Opciones de una lista fija (`kind = select`). */
|
||||
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`…). */
|
||||
lookup?: string;
|
||||
}
|
||||
@@ -70,12 +72,14 @@ export function paramsFromLoadCr(resultSet: readonly CrystalParameter[]): Gatewa
|
||||
.map((p) => {
|
||||
const type = p.type ?? 'xsd:string';
|
||||
const first = p.defaultValues?.[0];
|
||||
const decorative = /@(title|separator)$/i.test(p.name);
|
||||
return {
|
||||
name: p.name,
|
||||
type,
|
||||
label: (p.description ?? p.name).replace(/[:\s]+$/, '').replace(/^Especificar\s+/i, '') || p.name,
|
||||
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.allowMultiValue === 'true' ? { multiple: true } : {}),
|
||||
...(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 missing: string[] = [];
|
||||
for (const p of params) {
|
||||
if (p.hidden) continue;
|
||||
const raw = values[p.name];
|
||||
if (isBlank(raw)) {
|
||||
if (p.required) missing.push(p.label);
|
||||
|
||||
Reference in new issue
Block a user