Passed
Push — master ( e7acbe...c65cd9 )
by Esteban De La Fuente
19:00
created

AbstractReceiverHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 5
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * LibreDTE: Biblioteca PHP (Núcleo).
7
 * Copyright (C) LibreDTE <https://www.libredte.cl>
8
 *
9
 * Este programa es software libre: usted puede redistribuirlo y/o modificarlo
10
 * bajo los términos de la Licencia Pública General Affero de GNU publicada por
11
 * la Fundación para el Software Libre, ya sea la versión 3 de la Licencia, o
12
 * (a su elección) cualquier versión posterior de la misma.
13
 *
14
 * Este programa se distribuye con la esperanza de que sea útil, pero SIN
15
 * GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
16
 * PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la Licencia Pública
17
 * General Affero de GNU para obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de
20
 * GNU junto a este programa.
21
 *
22
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
23
 */
24
25
namespace libredte\lib\Core\Package\Billing\Component\Exchange\Abstract;
26
27
use Derafu\Lib\Core\Foundation\Abstract\AbstractHandler;
28
use libredte\lib\Core\Package\Billing\Component\Exchange\Contract\ExchangeBagInterface;
29
use libredte\lib\Core\Package\Billing\Component\Exchange\Contract\ExchangeHandlerInterface;
30
use libredte\lib\Core\Package\Billing\Component\Exchange\Contract\ReceiverStrategyInterface;
31
use libredte\lib\Core\Package\Billing\Component\Exchange\Contract\ReceiverWorkerInterface;
32
use libredte\lib\Core\Package\Billing\Component\Exchange\Exception\ExchangeException;
33
34
/**
35
 * Clase base para los handlers de receoción del proceso de intercambio.
36
 */
37
abstract class AbstractReceiverHandler extends AbstractHandler implements ExchangeHandlerInterface
38
{
39
    /**
40
     * Constructor del handler.
41
     *
42
     * @param ReceiverWorkerInterface $receiverWorker
43
     * @param array $strategies Estrategias que este handler puede manejar.
44
     */
45
    public function __construct(
46
        private ReceiverWorkerInterface $receiverWorker,
47
        iterable $strategies = []
48
    ) {
49
        parent::__construct($strategies);
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function handle(ExchangeBagInterface $bag): array
56
    {
57
        // Verificar que la bolsa tenga lo necesario.
58
        // Esta es una revisión general del handler. Evita solicitar la
59
        // estrategia si no se debe procesar por este handler.
60
        if (!$this->hasRequiredData($bag)) {
61
            return [];
62
        }
63
64
        // Determinar qué estrategias se ejecutarán.
65
        $strategies = $this->resolveStrategies($bag);
66
        if (empty($strategies)) {
67
            return [];
68
        }
69
70
        // Iterar las estrategias.
71
        foreach ($strategies as $strategy) {
72
            // Recibir sobres usando el método receive() del worker.
73
            $bag->getOptions()->set('strategy', $strategy);
74
            $workerResults = $this->receiverWorker->receive($bag);
75
76
            // Agregar los resultados del worker a los resultados generales del
77
            // handler.
78
            foreach ($workerResults as $workerResult) {
79
                $bag->addResult($workerResult);
80
            }
81
        }
82
83
        // Entregar los resultados de la recepción con todas las estrategias que
84
        // se hayan ejecutado.
85
        return $bag->getResults();
86
    }
87
88
    /**
89
     * Determina si la bolsa tiene los datos mínimos necesarios.
90
     *
91
     * Estos datos mínimos son independientes de la estrategia que use el
92
     * handler, pero están relacionados. Por ejemplo, estrategias que reciben
93
     * los documentos por correo electrónico requerirán los datos del
94
     * transporte.
95
     *
96
     * @param ExchangeBagInterface $bag
97
     * @return bool
98
     */
99
    abstract protected function hasRequiredData(ExchangeBagInterface $bag): bool;
100
101
    /**
102
     * Entrega las estrategias que efectivamente se pueden ejecutar con
103
     * la bolsa que se ha pasado.
104
     *
105
     * Este método revisa cada estrategia pasando la bolsa para saber si la
106
     * estrategia la puede procesar.
107
     *
108
     * @param ExchangeBagInterface $bag
109
     * @return string[] Códigos de las estrategias que se pueden ejecutar.
110
     */
111
    protected function resolveStrategies(ExchangeBagInterface $bag): array
112
    {
113
        $strategies = [];
114
115
        foreach ($this->getStrategies() as $name => $strategy) {
116
            assert($strategy instanceof ReceiverStrategyInterface);
117
            try {
118
                $strategy->canReceive($bag);
119
                $strategies[] = $name;
120
            } catch (ExchangeException $e) {
121
                // Falla silenciosamente pues no se puede procesar con esta
122
                // estrategia.
123
            }
124
        }
125
126
        return $strategies;
127
    }
128
}
129