1export function validPeriod(value) { 2 const year = Number(value?.year), month = Number(value?.month); 3 return Number.isInteger(year) && year >= 2015 && year <= 2100 && Number.isInteger(month) && month >= 1 && month <= 12 ? { year, month } : null; 4} 5 6export function closePriority(item) { 7 if (item.closing.status === 'closed') return 3; 8 return item.closing.blockers ? 0 : item.checks.some(check => check.status === 'review') ? 1 : 2; 9} 10 11export function firstCloseSteps(report) { 12 const source=report.source,fiscal=source.fiscal; 13 return [ 14 { label:'Empresa registrada',complete:true,operation:'empresas' }, 15 { label:'Reunir documentos',complete:Boolean(source.documentChecklist?.total)&&source.documentChecklist.approved===source.documentChecklist.total,operation:'clientRequests' }, 16 { label:'Importar CFDI',complete:source.xml.count>0,operation:'invoices' }, 17 { label:'Conciliar bancos',complete:Boolean(source.bank)&&!Number(source.bank.summary.review||0)&&!Number(source.bank.summary.unmatched||0),operation:'bankReconciliation' }, 18 { label:'Revisar pólizas',complete:source.accounting.total>0&&!source.accounting.pending,operation:'accountingCenter' }, 19 { label:'Revisar cálculo fiscal',complete:Boolean(fiscal?.rows?.length)&&fiscal.rows.every(row=>row.paper!==null&&Number.isFinite(row.paper)),operation:'workingPaper' }, 20 { label:'Declaraciones y acuses',complete:Boolean(source.presented)&&!(source.fiscalPending?.length),operation:'declarations' }, 21 { label:'Cruzar lo declarado',complete:Boolean(fiscal?.rows?.length)&&fiscal.summary.pending===0,operation:'cruceXml' }, 22 { label:'Cerrar y conservar expediente',complete:report.closing?.status==='closed',operation:'monthlyClose' }, 23 ]; 24}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.