-
Notifications
You must be signed in to change notification settings - Fork 153
Description
Hoy me topé con un detalle para en las retenciones. Si una factura de proveedor se paga en cuotas, es decir, tiene más de un pago y se van a realizar la retención con más de uno de ellos. No se puede hacer un loop de los pagos a pesar que el template lo permita.
Fragmento:
{% if det.pagos %}
{% for pay in det.pagos %}
<cac:Payment>
<cbc:ID>{{ loop.index }}</cbc:ID>
<cbc:PaidAmount currencyID="{{ pay.moneda }}">{{ pay.importe|n_format }}</cbc:PaidAmount>
<cbc:PaidDate>{{ pay.fecha|date('Y-m-d') }}</cbc:PaidDate>
</cac:Payment>
{% endfor %}
{% endif %}
Entonces, si se hace algo como esto:
sac:SUNATRetentionDocumentReference
<cbc:ID schemeID="01">FE01-2234</cbc:ID>
cbc:IssueDate2025-11-02</cbc:IssueDate>
<cbc:TotalInvoiceAmount currencyID="PEN">30.00</cbc:TotalInvoiceAmount>
cac:Payment
cbc:ID1</cbc:ID>
<cbc:PaidAmount currencyID="PEN">30.00</cbc:PaidAmount>
cbc:PaidDate2025-11-01</cbc:PaidDate>
</cac:Payment>
cac:Payment
cbc:ID2</cbc:ID>
<cbc:PaidAmount currencyID="PEN">36.00</cbc:PaidAmount>
cbc:PaidDate2025-11-01</cbc:PaidDate>
</cac:Payment>
sac:SUNATRetentionInformation
<sac:SUNATRetentionAmount currencyID="PEN">1.98</sac:SUNATRetentionAmount>
sac:SUNATRetentionDate2025-11-09</sac:SUNATRetentionDate>
<sac:SUNATNetTotalPaid currencyID="PEN">64.02</sac:SUNATNetTotalPaid>
</sac:SUNATRetentionInformation>
</sac:SUNATRetentionDocumentReference>
Nos genera el siguiente error:
Error al enviar a SUNAT: 0306 | {'message':'No se puede leer (parsear) el archivo XML - Detalle: http://xxx.xxx.xxx/ol-ti-itemision-otroscpe-gem/guia_remision_gem: cvc-complex-type 2.4: in element {urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1}SUNATRetentionDocumentReference of type {urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1}SUNATRetentionDocumentReferenceType, found (in namespace urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2), but next item should be end-element'}
Esto se debe a que dentro del XSD:
<!-- Retencion -->
<xsd:complexType name="SUNATRetentionDocumentReferenceType">
<xsd:sequence>
<xsd:element ref="cbc:ID" />
<xsd:element ref="cbc:IssueDate" />
<xsd:element ref="cbc:TotalInvoiceAmount" />
<xsd:element ref="cac:Payment" minOccurs="0" maxOccurs="1" />
<xsd:element ref="SUNATRetentionInformation" minOccurs="0"
maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SUNATRetentionInformationType">
<xsd:sequence>
<xsd:element ref="SUNATRetentionAmount" />
<xsd:element ref="SUNATRetentionDate" />
<xsd:element ref="SUNATNetTotalPaid" />
<xsd:element ref="cac:ExchangeRate" minOccurs="0"
maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SUNATRetentionDateType">
<xsd:simpleContent>
<xsd:extension base="udt:DateType" />
</xsd:simpleContent>
</xsd:complexType>
<!-- Fin Retencion -->
<xsd:element ref="cac:Payment" minOccurs="0" maxOccurs="1" />
Solo se puede hacer un pago por factura.
Por otro lado, para el número de pago se genera por un loop:
cbc:ID{{ loop.index }}</cbc:ID>
Entonces siempre será uno.
Entonces he agregado unos métodos para el número de pago:
/**
* Número de pago.
*
* @var int
*/
private $numero;
/**
* @return int
*/
public function getNumero(): ?int
{
return $this->numero;
}
/**
* @param float $numero
*
* @return Payment
*/
public function setNumero(?int $numero): Payment
{
$this->numero = $numero;
return $this;
}
y usarlo así:
$payment = (new Payment())
->setMoneda($currency)
->setFecha($date_payment)
->setImporte($amount)
->setNumero($r->payment_number);
De modo que se utilice el número de pago a la factura que se haya determinado en el sistema.
Con eso conseguí esto:
sac:SUNATRetentionDocumentReference
<cbc:ID schemeID="01">FE01-2234</cbc:ID>
cbc:IssueDate2025-11-02</cbc:IssueDate>
<cbc:TotalInvoiceAmount currencyID="PEN">66.00</cbc:TotalInvoiceAmount>
cac:Payment
cbc:ID1</cbc:ID>
<cbc:PaidAmount currencyID="PEN">30.00</cbc:PaidAmount>
cbc:PaidDate2025-11-01</cbc:PaidDate>
</cac:Payment>
cac:Payment
cbc:ID2</cbc:ID>
<cbc:PaidAmount currencyID="PEN">36.00</cbc:PaidAmount>
cbc:PaidDate2025-11-01</cbc:PaidDate>
</cac:Payment>
sac:SUNATRetentionInformation
<sac:SUNATRetentionAmount currencyID="PEN">1.98</sac:SUNATRetentionAmount>
sac:SUNATRetentionDate2025-11-09</sac:SUNATRetentionDate>
<sac:SUNATNetTotalPaid currencyID="PEN">64.02</sac:SUNATNetTotalPaid>
</sac:SUNATRetentionInformation>
</sac:SUNATRetentionDocumentReference>
y se aceptó el xml