fix(iva): exclude import-linked services from goods gift references
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { acquisitionBook, acquisitionScope } from './iva-acquisitions.ts';
|
import { acquisitionBook, acquisitionScope } from './iva-acquisitions.ts';
|
||||||
import { importExemptionBook } from './iva-import-exemptions.ts';
|
import { importExemptionBook,isImportService } from './iva-import-exemptions.ts';
|
||||||
|
|
||||||
type Choice = ''|'yes'|'no';
|
type Choice = ''|'yes'|'no';
|
||||||
export const offerPreparationSource='CIVA,Lei13/2016,14(2)(a/b) e14(3),PDF13/p.1426(271). Preparação de dados; procedimento regulamentar de aplicação ainda em pesquisa. Não concede isenção nem preenche dedução/campo11.';
|
export const offerPreparationSource='CIVA,Lei13/2016,14(2)(a/b) e14(3),PDF13/p.1426(271). Preparação de dados; procedimento regulamentar de aplicação ainda em pesquisa. Não concede isenção nem preenche dedução/campo11.';
|
||||||
@@ -34,7 +34,7 @@ export function recordOfferPreparations(book:OfferPreparationBook):OfferPreparat
|
|||||||
export type OfferReusable={key:string;label:string;operation:'acquisition'|'import';values:Partial<OfferPreparation>};
|
export type OfferReusable={key:string;label:string;operation:'acquisition'|'import';values:Partial<OfferPreparation>};
|
||||||
export function offerReusableData(draft:Record<string,unknown>):OfferReusable[]{
|
export function offerReusableData(draft:Record<string,unknown>):OfferReusable[]{
|
||||||
const purchases=acquisitionBook(draft).rows.map(row=>({key:'acquisition:'+row.id,label:'Aquisição: '+(row.description||row.documentRef||row.id),operation:'acquisition' as const,values:{description:row.description,period:row.period,currency:row.sourceCurrency,amount:row.net,documentRef:row.documentRef,documentDate:row.documentDate,counterparty:row.supplier}}));
|
const purchases=acquisitionBook(draft).rows.map(row=>({key:'acquisition:'+row.id,label:'Aquisição: '+(row.description||row.documentRef||row.id),operation:'acquisition' as const,values:{description:row.description,period:row.period,currency:row.sourceCurrency,amount:row.net,documentRef:row.documentRef,documentDate:row.documentDate,counterparty:row.supplier}}));
|
||||||
const imports=importExemptionBook(draft).rows.map(row=>({key:'import:'+row.id,label:'Importação: '+(row.description||row.documentRef||row.id),operation:'import' as const,values:{description:row.description,period:row.period,currency:row.currency,amount:row.declaredValue,documentRef:row.documentRef,documentDate:row.documentDate,counterparty:row.importer}}));
|
const imports=importExemptionBook(draft).rows.filter(row=>!isImportService(row.treatment)).map(row=>({key:'import:'+row.id,label:'Importação: '+(row.description||row.documentRef||row.id),operation:'import' as const,values:{description:row.description,period:row.period,currency:row.currency,amount:row.declaredValue,documentRef:row.documentRef,documentDate:row.documentDate,counterparty:row.importer}}));
|
||||||
return [...purchases,...imports];
|
return [...purchases,...imports];
|
||||||
}
|
}
|
||||||
export function reuseOfferData(row:OfferPreparation,source:OfferReusable):OfferPreparation {
|
export function reuseOfferData(row:OfferPreparation,source:OfferReusable):OfferPreparation {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import assert from 'node:assert/strict';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { newImportExemption,evaluateImportExemption,recordImportExemptions,saveImportExemptionBook,importExemptionBook,importExemptionCurrent,importExemptionRules,importServiceSource } from '../../resources/js/lib/iva-import-exemptions.ts';
|
import { newImportExemption,evaluateImportExemption,recordImportExemptions,saveImportExemptionBook,importExemptionBook,importExemptionCurrent,importExemptionRules,importServiceSource } from '../../resources/js/lib/iva-import-exemptions.ts';
|
||||||
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
||||||
|
import { offerReusableData } from '../../resources/js/lib/iva-offer-preparations.ts';
|
||||||
const frozen=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-offer-paths-inputs.json',import.meta.url),'utf8'));
|
const frozen=JSON.parse(fs.readFileSync(new URL('./fixtures/iva-offer-paths-inputs.json',import.meta.url),'utf8'));
|
||||||
const rules=importExemptionRules.filter(r=>r.branch==='P050');
|
const rules=importExemptionRules.filter(r=>r.branch==='P050');
|
||||||
const row=rule=>({...newImportExemption('g6f-'+rule.id,'MZN'),treatment:rule.id,description:'SYNTHETIC QA '+rule.label,period:'2026-12',declaredValue:'5000',importer:'SYNTHETIC QA importador destinatário',documentRef:'SYNTHETIC QA G6F '+rule.id,documentDate:'2026-11-14',evidence:'SYNTHETIC QA serviço e montante integral incluídos na base identificada, conforme artigo16; pressuposto expresso, não documento real',serviceImportRef:'SYNTHETIC QA importação DU-A,2026-12',serviceBaseRef:'SYNTHETIC QA base DU-A,linha serviço5000MZN',serviceProvider:'SYNTHETIC QA prestador',...(rule.id==='accessory_service_first_destination'?{serviceFirstDestination:'SYNTHETIC QA Manica,primeiro destino no documento de transporte'}:{}),conditions:Object.fromEntries(rule.conditions.map(([key])=>[key,'yes']))});
|
const row=rule=>({...newImportExemption('g6f-'+rule.id,'MZN'),treatment:rule.id,description:'SYNTHETIC QA '+rule.label,period:'2026-12',declaredValue:'5000',importer:'SYNTHETIC QA importador destinatário',documentRef:'SYNTHETIC QA G6F '+rule.id,documentDate:'2026-11-14',evidence:'SYNTHETIC QA serviço e montante integral incluídos na base identificada, conforme artigo16; pressuposto expresso, não documento real',serviceImportRef:'SYNTHETIC QA importação DU-A,2026-12',serviceBaseRef:'SYNTHETIC QA base DU-A,linha serviço5000MZN',serviceProvider:'SYNTHETIC QA prestador',...(rule.id==='accessory_service_first_destination'?{serviceFirstDestination:'SYNTHETIC QA Manica,primeiro destino no documento de transporte'}:{}),conditions:Object.fromEntries(rule.conditions.map(([key])=>[key,'yes']))});
|
||||||
@@ -25,4 +26,5 @@ test('save/recovery/report preserve27fiscalbooks and946fc089scenarios/requests/h
|
|||||||
test('old goods rows keep own tax representation and malformed optional service references cannot overwrite saved originals',()=>{
|
test('old goods rows keep own tax representation and malformed optional service references cannot overwrite saved originals',()=>{
|
||||||
const d=draft(),prior=JSON.parse(d.modelo_a_snapshot);for(const book of Object.values(prior.importExemptions))assert.ok(book.result.rows.every(row=>!Object.hasOwn(row,'serviceVat')));
|
const d=draft(),prior=JSON.parse(d.modelo_a_snapshot);for(const book of Object.values(prior.importExemptions))assert.ok(book.result.rows.every(row=>!Object.hasOwn(row,'serviceVat')));
|
||||||
assert.throws(()=>saveImportExemptionBook(d,{rows:[{...row(rules[0]),serviceBaseRef:42}]}),/Referências do serviço/);
|
assert.throws(()=>saveImportExemptionBook(d,{rows:[{...row(rules[0]),serviceBaseRef:42}]}),/Referências do serviço/);
|
||||||
|
const serviceOnly={...d,context_opportunity:'opportunity:336'};serviceOnly.modelo_a_snapshot=saveImportExemptionBook(serviceOnly,{rows:rules.map(row)});assert.equal(offerReusableData(serviceOnly).length,0,'P050 services cannot be reused as imported goods in P084');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user