export type FiscalProofParcel = { parcel?: string; parcelReference?: string }; export const canonicalParcel = (s: string) => s.normalize('NFKC').trim().toLocaleLowerCase('pt').replace(/\s+/g, ' '); export function validateProofParcel(r: FiscalProofParcel) { if ( (r.parcel !== undefined && typeof r.parcel !== 'string') || (r.parcelReference !== undefined && typeof r.parcelReference !== 'string') ) throw Error( 'Identificação da parcela documental não recuperável; original conservado.', ); } export function requireProofParcel(r: FiscalProofParcel) { validateProofParcel(r); if (!!r.parcel?.trim() !== !!r.parcelReference?.trim()) throw Error( 'Parcela documental e suporte devem corresponder; não se presume que linhas distintas representam impostos diferentes.', ); } export const parcelProjection = (r: FiscalProofParcel): FiscalProofParcel => ({ ...(r.parcel === undefined ? {} : { parcel: r.parcel }), ...(r.parcelReference === undefined ? {} : { parcelReference: r.parcelReference }), }); // Old proofs without a parcel cover the physical document. They overlap any newly identified parcel until reconciled. export const overlappingProofParcels = ( a: FiscalProofParcel & { identity: string }, b: FiscalProofParcel & { identity: string }, ) => a.identity === b.identity && (!a.parcel?.trim() || !b.parcel?.trim() || canonicalParcel(a.parcel) === canonicalParcel(b.parcel));