feat(web): la cuenta elegida completa la descripción de la línea de servicio y elegir el socio agrega una línea
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2e74bccd65
commit
773dd7ff6a
4 files changed
+36
-2
No files matched your search
@@ -210,6 +210,15 @@ describe('DocumentFormPage', () => {
|
|||||||
expect(navigate).toHaveBeenCalledWith(['..', 99], expect.objectContaining({ state: { created: '1099' } }));
|
expect(navigate).toHaveBeenCalledWith(['..', 99], expect.objectContaining({ state: { created: '1099' } }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('al elegir el socio de un documento nuevo sin líneas se agrega una línea, y no se repite', async () => {
|
||||||
|
expect(page().lines()).toEqual([]);
|
||||||
|
page().onPartner({ CardCode: 'C1', CardName: 'ACME' });
|
||||||
|
await tick();
|
||||||
|
expect(page().lines()).toHaveLength(1);
|
||||||
|
page().onPartner({ CardCode: 'C2', CardName: 'OTRO' });
|
||||||
|
expect(page().lines()).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
describe('tipo Servicio', () => {
|
describe('tipo Servicio', () => {
|
||||||
const headers = () => [...el().querySelectorAll('.lines-head th, table.grid thead th')].map((t) => t.textContent?.trim());
|
const headers = () => [...el().querySelectorAll('.lines-head th, table.grid thead th')].map((t) => t.textContent?.trim());
|
||||||
|
|
||||||
|
|||||||
@@ -429,6 +429,8 @@ export class DocumentFormPage {
|
|||||||
protected onPartner(row: Record<string, unknown>): void {
|
protected onPartner(row: Record<string, unknown>): void {
|
||||||
this.partnerName.set(text(row['CardName']));
|
this.partnerName.set(text(row['CardName']));
|
||||||
this.partnerTaxId.set(text(row['FederalTaxID']));
|
this.partnerTaxId.set(text(row['FederalTaxID']));
|
||||||
|
// elegido el socio, el documento nuevo arranca con una línea lista para escribir
|
||||||
|
if (this.isNew() && !this.readOnly() && this.lines().length === 0) this.lines.set([this.newLine()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setLines(lines: readonly GridLine[]): void {
|
protected setLines(lines: readonly GridLine[]): void {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { ANALYTIC_COLUMNS, DOCUMENT_LINE_COLUMNS, ITEMS_MULTI_ADD, lineColumnsFor, lineFieldsOf, newDocumentLine, recalcLine, uomEntryOf } from './line-columns';
|
import { ANALYTIC_COLUMNS, DOCUMENT_LINE_COLUMNS, ITEMS_MULTI_ADD, lineColumnsFor, lineFieldsOf, newDocumentLine, newServiceLine, recalcLine, serviceLineColumns, uomEntryOf } from './line-columns';
|
||||||
|
|
||||||
describe('recalcLine', () => {
|
describe('recalcLine', () => {
|
||||||
it('total = cantidad × precio, redondeado a 2 decimales', () => {
|
it('total = cantidad × precio, redondeado a 2 decimales', () => {
|
||||||
@@ -148,3 +148,12 @@ describe('precio con y sin impuesto', () => {
|
|||||||
expect(recalcLine({ ...base, Price: 50, PriceAfterVAT: 80 }, 'Quantity')).toMatchObject({ Price: 50, PriceAfterVAT: 80, LineTotal: 100 });
|
expect(recalcLine({ ...base, Price: 50, PriceAfterVAT: 80 }, 'Quantity')).toMatchObject({ Price: 50, PriceAfterVAT: 80, LineTotal: 100 });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('línea de servicio', () => {
|
||||||
|
const account = serviceLineColumns()[0].lookup!;
|
||||||
|
|
||||||
|
it('al elegir la cuenta, su nombre es la descripción si la línea no tiene otra', () => {
|
||||||
|
expect(account.apply({ Code: '_SYS1', Name: 'Alquileres' }, newServiceLine())).toMatchObject({ AccountCode: '_SYS1', ItemDescription: 'Alquileres' });
|
||||||
|
expect(account.apply({ Code: '_SYS1', Name: 'Alquileres' }, { ...newServiceLine(), ItemDescription: 'Oficina' })).toMatchObject({ AccountCode: '_SYS1', ItemDescription: 'Oficina' });
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -212,7 +212,21 @@ export const LINE_COLUMNS = {
|
|||||||
*/
|
*/
|
||||||
export const serviceLineColumns = (taxResource = 'SalesTaxCodes'): readonly GridColumn[] =>
|
export const serviceLineColumns = (taxResource = 'SalesTaxCodes'): readonly GridColumn[] =>
|
||||||
lineColumnsFor(taxResource, [
|
lineColumnsFor(taxResource, [
|
||||||
{ ...LINE_COLUMNS.account, title: 'Cuenta contable', width: '170px', required: true },
|
{
|
||||||
|
...LINE_COLUMNS.account,
|
||||||
|
title: 'Cuenta contable',
|
||||||
|
width: '170px',
|
||||||
|
required: true,
|
||||||
|
// al elegir la cuenta, su nombre es la descripción de la línea (si no se escribió otra)
|
||||||
|
lookup: {
|
||||||
|
...LINE_COLUMNS.account.lookup!,
|
||||||
|
apply: (account, line) => ({
|
||||||
|
...line,
|
||||||
|
AccountCode: account['Code'],
|
||||||
|
ItemDescription: filled(line['ItemDescription']) ? line['ItemDescription'] : (account['Name'] ?? ''),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ ...LINE_COLUMNS.description, width: '260px' },
|
{ ...LINE_COLUMNS.description, width: '260px' },
|
||||||
LINE_COLUMNS.tax,
|
LINE_COLUMNS.tax,
|
||||||
{ ...LINE_COLUMNS.total, readonly: false, required: true },
|
{ ...LINE_COLUMNS.total, readonly: false, required: true },
|
||||||
|
|||||||
Reference in new issue
Block a user