feat(web): formularios de inventario y solicitudes de compra (entradas, salidas, transferencias, solicitudes de traslado)

Configuración declarativa en document-layouts.ts; las líneas de las transferencias van en
StockTransferLines y las de compra/inventario llevan UoMEntry si el artículo tiene grupo de unidades.
Probado contra SBODemoCL (solicitud de compra 2, solicitud de traslado 472, entrada 155).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5.5 committed 2026-10-14 14:37:01 -05:00
1 parent 45c0ca536e
commit 155d18fce4
13 files changed
+550 -46

No files matched your search

@@ -81,11 +81,46 @@
<sbo-text-field label="Total del documento" readonly [value]="fmt(totals().total)" />
</div>
</div>
} @else if (layout; as lay) {
<div class="sbo-hdr">
<div class="sbo-col">
@for (f of lay.left; track f.key) {
<ng-container *ngTemplateOutlet="field; context: { $implicit: f }" />
}
</div>
<div class="sbo-col">
<sbo-text-field label="Número" readonly [value]="str(doc()?.['DocNum'])" />
@for (f of lay.right; track f.key) {
<ng-container *ngTemplateOutlet="field; context: { $implicit: f }" />
}
</div>
</div>
<sbo-lines-grid
[columns]="columns"
[lines]="lines()"
(linesChange)="setLines($event)"
(notice)="notify($event)"
[readonly]="readOnly()"
[newLine]="newLine"
[multiAdd]="multi"
/>
<div class="sbo-hdr" style="margin-top: 14px">
<div class="sbo-col">
<sbo-textarea-field
label="Comentarios"
[readonly]="readOnly()"
[value]="str(header()['Comments'])"
(valueChange)="setHeader('Comments', $event)"
/>
</div>
</div>
} @else {
<p>El formulario de este documento aún no está disponible. <a routerLink="..">Volver a la lista</a></p>
}
@if (partner && !readOnly()) {
@if ((partner || layout) && !readOnly()) {
<button sboActions class="btn main" type="button" [disabled]="saving() || loading()" (click)="save()">
{{ isNew() ? 'Crear' : 'Actualizar' }}
</button>
@@ -115,3 +150,36 @@
(closed)="copyListFor.set(null)"
/>
}
<ng-template #field let-f>
@switch (f.type) {
@case ('date') {
<sbo-date-field
[label]="f.label"
[required]="!!f.required"
[readonly]="readOnly()"
[value]="str(header()[f.key])"
(valueChange)="setHeader(f.key, $event)"
/>
}
@case ('warehouse') {
<sbo-lookup-field
[label]="f.label"
[required]="!!f.required"
[readonly]="readOnly()"
[value]="str(header()[f.key])"
(valueChange)="setHeader(f.key, $event)"
[lookup]="warehouseLookup"
resolveOnLeave
/>
}
@default {
<sbo-text-field
[label]="f.label"
[readonly]="readOnly()"
[value]="str(header()[f.key])"
(valueChange)="setHeader(f.key, $event)"
/>
}
}
</ng-template>