When building a CFDI, theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/eclipxe13/CfdiUtils/llms.txt
Use this file to discover all available pages before exploring further.
SubTotal, Total, Descuento, and the aggregate tax amounts (TotalImpuestosTrasladados, TotalImpuestosRetenidos) must match the sum of values across every Concepto node in the document. Doing this by hand is error-prone and tedious. CfdiUtils\SumasConceptos\SumasConceptos solves the problem by reading the Conceptos tree from a Comprobante node and computing all the required totals for you — including federal taxes (IVA, ISR, IEPS), exempt (Exento) entries, and local taxes from the ImpuestosLocales complement.
Once the totals are computed, the companion class SumasConceptosWriter writes them back into the appropriate XML attributes and child nodes. When using CfdiCreator40 (or CfdiCreator33), both steps are wrapped in the single convenience method addSumasConceptos().
Constructor
The root
Comprobante node (any NodeInterface implementation). SumasConceptos searches for cfdi:Conceptos/cfdi:Concepto children automatically.Number of decimal places used when rounding each intermediate and final total. A precision of
2 is correct for standard MXN invoices. Use 6 when you need extra accuracy (e.g. when passing values to SumasConceptosWriter which defaults to 6-decimal formatting).Available Getters
After construction, the following read-only values are available:Sum of all
Concepto/@Importe values, rounded to $precision decimal places.Sum of all
Concepto/@Descuento values, rounded to $precision. Returns 0.0 when no concepto carries a discount.The final invoice total:
SubTotal − Descuento + TotalImpuestosTrasladados − TotalImpuestosRetenidos + LocalesTrasladados − LocalesRetenidos, rounded to $precision.Sum of all federal transfer-tax (
Traslado) amounts, rounded to $precision. Exempt (Exento) entries are not included.Sum of all federal withholding-tax (
Retencion) amounts, rounded to $precision.Associative array of aggregated transfer-tax entries keyed by
Impuesto:TipoFactor:TasaOCuota. Each entry contains Impuesto, TipoFactor, TasaOCuota, Importe (float), and Base (float).Associative array of exempt transfer-tax entries (where
TipoFactor = 'Exento'). Each entry contains Impuesto, TipoFactor, and Base (float).Associative array of aggregated withholding-tax entries. Each entry contains
Impuesto and Importe (float).Total local transfer-tax amount from the
ImpuestosLocales complement.Total local withholding-tax amount from the
ImpuestosLocales complement.Array of local transfer-tax entries. Each entry contains
Impuesto (string), Tasa (float), and Importe (float).Array of local withholding-tax entries. Each entry contains
Impuesto (string), Tasa (float), and Importe (float).Returns the precision value the object was constructed with.
Returns
true if at least one Concepto node had a Descuento attribute present, even if its value is zero. Used by SumasConceptosWriter to decide whether to write or omit the Comprobante/@Descuento attribute.Has-checkers
| Method | Returns true when… |
|---|---|
hasTraslados(): bool | At least one non-exempt transfer tax exists |
hasExentos(): bool | At least one exempt transfer-tax entry exists |
hasRetenciones(): bool | At least one federal withholding tax exists |
hasLocalesTraslados(): bool | At least one local transfer tax from ImpuestosLocales exists |
hasLocalesRetenciones(): bool | At least one local withholding tax from ImpuestosLocales exists |
Using with CfdiCreator40
The easiest way to applySumasConceptos is through the addSumasConceptos() method available on both CfdiCreator40 and CfdiCreator33. It creates a SumasConceptos instance internally and passes the results to SumasConceptosWriter, which writes all totals back into the XML in one step.
Inspecting values before writing
Using Standalone
You can useSumasConceptos independently of any creator, for example to validate an existing CFDI or to read computed totals without modifying the XML.
Precision
The$precision parameter controls the number of decimal places used at every rounding step during the aggregation. This affects:
- Each grouped
TrasladoandRetencionimporte and base. - The aggregated
getImpuestosTrasladados()andgetImpuestosRetenidos()values. - The individual components of
getTotal()before the final sum.
SumasConceptosWriter has its own $precision parameter (defaulting to 6) that controls how the float values are formatted as strings when written into XML attributes. You can pass different values to SumasConceptos (for aggregation rounding) and SumasConceptosWriter (for string formatting) independently.
The SAT Anexo 20 requires amounts to be expressed with up to 6 decimal places. Using a precision lower than 2 is unusual, and precision higher than 6 is capped by the XML schema. For most invoices,
precision = 2 for aggregation and precision = 6 for formatting is the recommended combination (which is what addSumasConceptos() uses by default).Static Helper
impuestoKey(string $impuesto, string $tipoFactor = '', string $tasaOCuota = ''): string generates the string key used to group identical tax entries in the getTraslados() and getRetenciones() arrays.