Code

< 40 %
40-60 %
> 60 %
1
<?php
2
3
namespace CfdiUtils\Utils;
4
5
use CfdiUtils\Nodes\NodeInterface;
6
7
/**
8
 * This utility class change the /pago20:Pagos/pago20:Pago/pago20:DoctoRelacionado@EquivalenciaDR attribute
9
 * from '1' to '1.0000000000' as defined by the rule CRP20277.
10
 *
11
 * La regla CRP20277 está definida en los Documentos técnicos del complemento de recepción de pagos 2.0, revisión B,
12
 * vigente a partir del 15 de enero de 2024, en la Matriz de errores, y dice:
13
 * Validación:
14
 *   Cuando existan operaciones con más de un Documento relacionado en donde al menos uno de ellos contenga
15
 *   la misma moneda que la del Pago, para la fórmula en el cálculo del margen de variación se deben
16
 *   considerar 10 decimales en la EquivalenciaDR cuando el valor sea 1.
17
 * Código de error:
18
 *   El campo EquivalenciaDR debe contener el valor "1.0000000000".
19
 * Esta regla cambia lo especificado en la regla CRP20238.
20
 *
21
 * Deprecación:
22
 * El código de error cambió el 2024-01-16 a:
23
 *   El valor de EquivalenciaDR para la fórmula del cálculo del margen de variación debe ser “1.0000000000”.
24
 * Por lo tanto, no es necesario hacer el cambio de valores en el CFDI.
25
 *
26
 * @see http://omawww.sat.gob.mx/tramitesyservicios/Paginas/recepcion_de_pagos.htm
27
 * @deprecated 2.28.0 No es necesario mantener esta clase y será removida en una nueva versión mayor.
28
 */
29
final class Crp20277Fixer
30
{
31 1
    public static function staticFix(NodeInterface $complemento): void
32
    {
33 1
        $fixer = new self();
34 1
        $fixer->fixPagos($complemento);
35
    }
36
37 1
    public function fixPagos(NodeInterface $complemento): void
38
    {
39 1
        $pagos = $complemento->searchNodes('pago20:Pago');
40 1
        foreach ($pagos as $pago) {
41 1
            $this->fixPago($pago);
42
        }
43
    }
44
45 1
    public function fixPago(NodeInterface $pago): void
46
    {
47 1
        $doctoRelacionados = $pago->searchNodes('pago20:DoctoRelacionado');
48
49
        // más de un Documento relacionado
50 1
        if ($doctoRelacionados->count() < 2) {
51 1
            return;
52
        }
53
54
        // al menos uno de ellos contenga la misma moneda que la del Pago
55 1
        $hasDocumentsWithSameCurrency = false;
56 1
        foreach ($doctoRelacionados as $doctoRelacionado) {
57 1
            if ($doctoRelacionado['MonedaDR'] === $pago['MonedaP']) {
58 1
                $hasDocumentsWithSameCurrency = true;
59 1
                break;
60
            }
61
        }
62 1
        if (! $hasDocumentsWithSameCurrency) {
63
            return;
64
        }
65
66
        // se deben considerar 10 decimales en la EquivalenciaDR cuando el valor sea 1
67 1
        foreach ($doctoRelacionados as $doctoRelacionado) {
68 1
            if ('1' === $doctoRelacionado['EquivalenciaDR']) {
69 1
                $doctoRelacionado['EquivalenciaDR'] = '1.0000000000'; // CRP20277
70
            }
71
        }
72
    }
73
}
74