<?php

declare(strict_types=1);

/**
 * Export comptable des commandes / remboursements
 */
class OrderExporter
{
    /**
     * Comptes produits par pays et par taux de tva
     */
    public const PR_BY_CTRY
        = [
            8 => ['5.5' => '7071101', '10' => '7071102', '20' => '70711'], // France
            19 => ['5.5' => '7071301', '10' => '7071302', '20' => '70713'], // Suisse
        ];

    /**
     * Comptes TVA par taux de TVA
     */
    public const TVA_BY_TAUX
        = [
            '5.5' => '4457111',
            '10' => '4457113',
            '20' => '445711',
        ];

    /**
     * @var OrderInvoice
     */
    protected $orderInvoice;

    /**
     * @var Order
     */
    protected $order;

    /**
     * @var Address
     */
    protected $addressInvoice;

    /**
     * @var OrderPayment[]
     */
    protected $orderPayments;

    /**
     * @var OrderSlip[]
     */
    protected $orderSlips;

    /**
     * Calcul du taux de TVA en fonction du prix TTC et tu prix HT
     *
     * @throws Exception
     */
    protected static function calculTauxTva(float $prixTTC, float $prixHT): float
    {
        // Si la TVA est à 0, retourn 20% par défaut
        if (0 == $prixHT) {
            return 20.0;
        }

        $distanceTrouvee = null;
        $tauxTrouve = null;

        $tauxPossibles = [5.5, 10.0, 20.0];
        foreach ($tauxPossibles as $tauxPossible) {
            $ttc = round($prixHT * (1 + ($tauxPossible / 100)), 2);
            $distance = round(abs($ttc - $prixTTC), 2);

            if (null === $tauxTrouve || $distance < $distanceTrouvee) {
                $tauxTrouve = $tauxPossible;
                $distanceTrouvee = $distance;
            }
        }

        if ($prixHT <= 2.0 && $distanceTrouvee <= 0.01) {
            return $tauxTrouve;
        } elseif ($distanceTrouvee <= 0.03) {
            return $tauxTrouve;
        }

        // Impossible de déterminer le taux !
        throw new Exception('Taux de TVA inconnu : ' . $tauxTrouve . ' (' . $prixHT . ')');
    }

    /**
     * Export de la TVA détaillée pour une commande
     *
     * @return array<int|string, float|int>
     */
    protected function getGlobalOrderTVA(): array
    {
        $ret = [
            '5.5' => 0,
            '10' => 0,
            '20' => 0,
        ];

        // + TVA Sur les frais de port
        $tvaFdp = $this->orderInvoice->total_shipping_tax_incl - $this->orderInvoice->total_shipping_tax_excl;
        if ($tvaFdp) {
            $tauxTvaFdp = self::calculTauxTva(floatval($this->orderInvoice->total_shipping_tax_incl), floatval($this->orderInvoice->total_shipping_tax_excl));
            $ret[strval($tauxTvaFdp)] += $tvaFdp;
        }

        // + TVA sur les produits
        /** @var OrderDetail[] $orderDetails */
        $orderDetails = ObjectModel::hydrateCollection(
            OrderDetail::class,
            $this->order->getOrderDetailList()
        );
        foreach ($orderDetails as $orderDetail) {
            $tvaProduit = $orderDetail->total_price_tax_incl - $orderDetail->total_price_tax_excl;
            if (!$tvaProduit) {
                continue;
            }

            $taxTvaProduit = self::calculTauxTva(floatval($orderDetail->total_price_tax_incl), floatval($orderDetail->total_price_tax_excl));

            $ret[strval($taxTvaProduit)] += $tvaProduit;
        }

        // - TVA sur les réductions
        $tvaDiscount = $this->orderInvoice->total_discount_tax_incl - $this->orderInvoice->total_discount_tax_excl;
        if ($tvaDiscount) {
            //$taxTvaDiscount               = self::calculTauxTva(floatval($this->orderInvoice->total_discount_tax_incl), floatval($this->orderInvoice->total_discount_tax_excl));
            // Par défaut on considère que le taux de TVA sur les réductions est de 20%
            $taxTvaDiscount = 20;
            $ret[strval($taxTvaDiscount)] -= $tvaDiscount;
        }

        return $ret;
    }

    /**
     * Calcul du montant HT des produits, classés par taux de TVA appliquée
     *
     * @return array<int|string, float|int>
     */
    protected function getProductInvoiceHtByTVA(): array
    {
        $ret = [
            '5.5' => 0,
            '10' => 0,
            '20' => 0,
        ];

        // + TVA sur les produits
        /** @var OrderDetail[] $orderDetails */
        $orderDetails = ObjectModel::hydrateCollection(
            OrderDetail::class,
            $this->order->getOrderDetailList()
        );
        foreach ($orderDetails as $orderDetail) {
            $tvaProduit = $orderDetail->total_price_tax_incl - $orderDetail->total_price_tax_excl;
            if (!$tvaProduit) {
                // Cas spécial : les suisses ne payaient pas de TVA
                $ret['20'] += $orderDetail->total_price_tax_excl;
            } else {
                $taxTvaProduit = self::calculTauxTva(floatval($orderDetail->total_price_tax_incl), floatval($orderDetail->total_price_tax_excl));

                $ret[strval($taxTvaProduit)] += $orderDetail->total_price_tax_excl;
            }
        }

        return $ret;
    }

    /**
     * Export de la TVA détaillée pour une commande
     *
     * @return array<int|string, float|int>
     */
    protected function getGlobalOrderSlipTVA(OrderSlip $orderSlip): array
    {
        $ret = [
            '5.5' => 0,
            '10' => 0,
            '20' => 0,
        ];

        // + TVA Sur les frais de port
        $tvaFdp = $orderSlip->total_shipping_tax_incl - $orderSlip->total_shipping_tax_excl;
        if ($tvaFdp) {
            $tauxTvaFdp = self::calculTauxTva(floatval($orderSlip->total_shipping_tax_incl), floatval($orderSlip->total_shipping_tax_excl));
            $ret[strval($tauxTvaFdp)] += $tvaFdp;
        }

        // + TVA sur les produits
        /** @var array[] $orderSlipDetails */
        $orderSlipDetails = Db::getInstance(false)->executeS(
            'SELECT * FROM `' . _DB_PREFIX_ . 'order_slip_detail` WHERE `id_order_slip` = ' . (int) ($orderSlip->id)
        );
        foreach ($orderSlipDetails as $orderSlipDetail) {
            $tvaProduit = $orderSlipDetail['total_price_tax_incl'] - $orderSlipDetail['total_price_tax_excl'];
            if (!$tvaProduit) {
                continue;
            }

            $taxTvaProduit = self::calculTauxTva(floatval($orderSlipDetail['total_price_tax_incl']), floatval($orderSlipDetail['total_price_tax_excl']));

            $ret[strval($taxTvaProduit)] += $tvaProduit;
        }

        // - TVA sur les réductions
        if (1 == $orderSlip->order_slip_type) {
            $cartRules = $this->order->getCartRules();
            $discounts = [
                'tax_excl' => 0,
                'tax_incl' => 0,
            ];
            $discounts = array_reduce(
                $cartRules,
                function ($carry, $cartRule) {
                    $carry['tax_excl'] += $cartRule['value_tax_excl'];
                    $carry['tax_incl'] += $cartRule['value'];

                    return $carry;
                },
                $discounts
            );

            $tvaDiscount = $discounts['tax_incl'] - $discounts['tax_excl'];
            if ($tvaDiscount) {
                //$taxTvaDiscount               = self::calculTauxTva(floatval($discounts['tax_incl']), floatval($discounts['tax_excl']));
                // Par défaut on considère que le taux de TVA sur les réductions est de 20%
                $taxTvaDiscount = 20;
                $ret[strval($taxTvaDiscount)] -= $tvaDiscount;
            }
        }

        return $ret;
    }

    /**
     * Calcul du montant HT des produits, classés par taux de TVA appliquée
     *
     * @return array<int|string, (float|int)>
     */
    protected function getProductOrderSlipHtByTVA(OrderSlip $orderSlip): array
    {
        $ret = [
            '5.5' => 0,
            '10' => 0,
            '20' => 0,
        ];

        // + TVA sur les produits
        /** @var array[] $orderSlipDetails */
        $orderSlipDetails = Db::getInstance(false)->executeS(
            'SELECT * FROM `' . _DB_PREFIX_ . 'order_slip_detail` WHERE `id_order_slip` = ' . (int) ($orderSlip->id)
        );
        foreach ($orderSlipDetails as $orderSlipDetail) {
            $tvaProduit = $orderSlipDetail['total_price_tax_incl'] - $orderSlipDetail['total_price_tax_excl'];
            if (!$tvaProduit) {
                // Cas spécial : les suisses ne payaient pas de TVA
                $ret['20'] += $orderSlipDetail['total_price_tax_excl'];
            } else {
                $taxTvaProduit = self::calculTauxTva(floatval($orderSlipDetail['total_price_tax_incl']), floatval($orderSlipDetail['total_price_tax_excl']));

                $ret[strval($taxTvaProduit)] += $orderSlipDetail['total_price_tax_excl'];
            }
        }

        // - TVA sur les réductions
        /*
        $tvaDiscount = $this->orderInvoice->total_discount_tax_incl - $this->orderInvoice->total_discount_tax_excl;
        if ($tvaDiscount) {
            $taxTvaDiscount               = self::calculTauxTva(floatval($this->orderInvoice->total_discount_tax_incl), floatval($this->orderInvoice->total_discount_tax_excl));
            $ret[strval($taxTvaDiscount)] -= $this->orderInvoice->total_discount_tax_excl;
        }
        */

        return $ret;
    }

    /**
     * @return array<int, array<string,float|int|string>>
     */
    protected function getLignesComptablesFacture(): array
    {
        $invoiceDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $this->order->invoice_date);
        $ret = [];
        $totalPayments = array_reduce(
            $this->orderPayments,
            function (float $carry, OrderPayment $orderPayment) {
                $carry += $orderPayment->amount;

                return $carry;
            },
            0.0
        );

        if (!$invoiceDate instanceof DateTimeImmutable) {
            throw new Exception('La date de la facture n\'a pu être récupérée.');
        }

        // 1 - Montant payé par le client [4110001]
        $ret[] = [
            'date' => $invoiceDate->format('d/m/Y'),
            'journal' => 'VE',
            'compte' => '4110001',
            'intitule' => 'Vente internet',
            'nofacture' => $this->orderInvoice->number,
            'debit' => round($this->orderInvoice->total_paid_tax_incl, 2),
            'credit' => 0.00,
        ];

        // 2 - Montant des remises (HT) [7097]
        if ($this->orderInvoice->total_discount_tax_excl > 0) {
            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '7097',
                'intitule' => 'Vente internet',
                'nofacture' => $this->orderInvoice->number,
                'debit' => round($this->orderInvoice->total_discount_tax_excl, 2),
                'credit' => 0.00,
            ];
        }

        // 3 - TVA Totale réglée par le client [445711]
        $tvas = $this->getGlobalOrderTVA();
        foreach ($tvas as $taux => $montant) {
            if (!$montant) {
                continue;
            }

            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => self::TVA_BY_TAUX[$taux],
                'intitule' => 'Vente internet',
                'nofacture' => $this->orderInvoice->number,
                'debit' => 0.00,
                'credit' => round($montant, 2),
            ];
        }

        // 4 - Total produits HT réglé [70711, 70112, 70713]
        $produits = $this->getProductInvoiceHtByTVA();
        foreach ($produits as $taux => $montant) {
            if (!$montant) {
                continue;
            }

            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => isset(OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country][$taux])
                    ? OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country][$taux] : 70112,
                'intitule' => 'Vente internet',
                'nofacture' => $this->orderInvoice->number,
                'debit' => 0.00,
                'credit' => round($montant, 2),
            ];
        }

        // 5 - Total frais de port HT [7080001]
        if ($this->orderInvoice->total_shipping_tax_excl > 0) {
            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '7080001',
                'intitule' => 'Vente internet',
                'nofacture' => $this->orderInvoice->number,
                'debit' => 0.00,
                'credit' => round($this->orderInvoice->total_shipping_tax_excl, 2),
            ];
        }

        // 6 - Commission bancaire (débit) [627]
        $ret[] = [
            'date' => $invoiceDate->format('d/m/Y'),
            'journal' => 'VE',
            'compte' => '627',
            'intitule' => 'Vente internet',
            'nofacture' => $this->orderInvoice->number,
            'debit' => round($totalPayments * 0.29 / 100, 2),
            'credit' => 0.00,
        ];

        // 7 - Commission bancaire (crédit) [4000018]
        $ret[] = [
            'date' => $invoiceDate->format('d/m/Y'),
            'journal' => 'VE',
            'compte' => '4000018',
            'intitule' => 'Vente internet',
            'nofacture' => $this->orderInvoice->number,
            'debit' => 0.00,
            'credit' => round($totalPayments * 0.29 / 100, 2),
        ];

        // 8 - Micro-Don pour JungleVet
        $cart = new Cart($this->order->id_cart);
        if ($cart->donation_amount > 0) {
            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'OD',
                'compte' => '4110001',
                'intitule' => 'Micro-Don',
                'nofacture' => $this->orderInvoice->number,
                'debit' => round($cart->donation_amount, 2),
                'credit' => 0.00,
            ];
            $ret[] = [
                'date' => $invoiceDate->format('d/m/Y'),
                'journal' => 'OD',
                'compte' => '4675',
                'intitule' => 'Micro-Don',
                'nofacture' => $this->orderInvoice->number,
                'debit' => 0.00,
                'credit' => round($cart->donation_amount, 2),
            ];
        }

        return $ret;
    }

    /**
     * @return array<int, array<string, array<int|string,string>|float|int|string>>
     */
    protected function getLignesComptablesAvoir(OrderSlip $orderSlip): array
    {
        $orderSlipDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $orderSlip->date_add);
        if (!$orderSlipDate instanceof DateTimeImmutable) {
            throw new Exception('La date du bon de commande n\'a pu être réccupérée.');
        }
        $ret = [];

        if ($orderSlip->has_voucher) {
            // Remboursement sous forme d'un bon de réduction
            // 1 - Montant payé par le client [4110001]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '4110001',
                'intitule' => 'Remboursement internet BR',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => 0.00,
                'credit' => round($orderSlip->total_products_tax_incl, 2),
            ];

            // 3 - TVA Totale réglée par le client [445711]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '445711',
                'intitule' => 'Remboursement internet BR',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => round($orderSlip->total_products_tax_incl - $orderSlip->total_products_tax_excl, 2),
                'credit' => 0.00,
            ];
            // TODO : Mettre à jour les comptes :
            /*
             *  70711 :   Ventes internet 20% (celui qu’on utilise actuellement)
                7071101 : Ventes internet 5,5%
                7071102 : Ventes internet 10%

                70713   :  Ventes internet SUISSE autre que UE 20%  (celui qu’on utilise actuellement)
                7071301 : Ventes internet SUISSE autre que UE 5,5%
                7071302 : Ventes internet SUISSE autre que UE 10%
             */

            // 4 - Total produits HT réglé [70711, 70112, 70713]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => isset(OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country])
                    ? OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country] : 70112,
                'intitule' => 'Remboursement internet BR',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => round($orderSlip->total_products_tax_excl, 2),
                'credit' => 0.00,
            ];
        } else {
            // Remboursement sur la CB
            $total_discounts_tax_excl = 0;
            $total_discounts_tax_incl = 0;
            if (1 == $orderSlip->order_slip_type) {
                $cartRules = $this->order->getCartRules();
                $discounts = [
                    'tax_excl' => 0,
                    'tax_incl' => 0,
                ];
                $discounts = array_reduce(
                    $cartRules,
                    function ($carry, $cartRule) {
                        $carry['tax_excl'] += $cartRule['value_tax_excl'];
                        $carry['tax_incl'] += $cartRule['value'];

                        return $carry;
                    },
                    $discounts
                );

                $total_discounts_tax_excl = $discounts['tax_excl'];
                $total_discounts_tax_incl = $discounts['tax_incl'];
            }

            // 1 - Montant payé par le client [4110001]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '4110001',
                'intitule' => 'Remboursement internet CB',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => 0.00,
                'credit' => round($orderSlip->total_products_tax_incl + $orderSlip->total_shipping_tax_incl - $total_discounts_tax_incl, 2),
            ];

            // 2 - Montant des remises (HT) [7097]
            if ($total_discounts_tax_excl > 0) {
                $ret[] = [
                    'date' => $orderSlipDate->format('d/m/Y'),
                    'journal' => 'VE',
                    'compte' => '7097',
                    'intitule' => 'Remboursement internet CB',
                    'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                    'debit' => 0.00,
                    'credit' => round($total_discounts_tax_excl, 2),
                ];
            }

            // 3 - TVA Totale réglée par le client [445711]
            $tvas = $this->getGlobalOrderSlipTVA($orderSlip);
            foreach ($tvas as $taux => $montant) {
                if (!$montant) {
                    continue;
                }

                $ret[] = [
                    'date' => $orderSlipDate->format('d/m/Y'),
                    'journal' => 'VE',
                    'compte' => self::TVA_BY_TAUX[$taux],
                    'intitule' => 'Remboursement internet CB',
                    'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                    'debit' => round(
                        $montant,
                        2
                    ),
                    'credit' => 0.00,
                ];
            }

            // 4 - Total produits HT réglé [70711, 70112, 70713]
            $produits = $this->getProductOrderSlipHtByTVA($orderSlip);
            foreach ($produits as $taux => $montant) {
                if (!$montant) {
                    continue;
                }

                $ret[] = [
                    'date' => $orderSlipDate->format('d/m/Y'),
                    'journal' => 'VE',
                    'compte' => isset(OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country][$taux])
                        ? OrderExporter::PR_BY_CTRY[$this->addressInvoice->id_country][$taux] : 70112,
                    'intitule' => 'Remboursement internet CB',
                    'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                    'debit' => round($montant, 2),
                    'credit' => 0.00,
                ];
            }

            // 5 - Total frais de port HT [7080001]
            if ($orderSlip->total_shipping_tax_excl > 0) {
                $ret[] = [
                    'date' => $orderSlipDate->format('d/m/Y'),
                    'journal' => 'VE',
                    'compte' => '7080001',
                    'intitule' => 'Remboursement internet CB',
                    'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                    'debit' => round($orderSlip->total_shipping_tax_excl, 2),
                    'credit' => 0.00,
                ];
            }

            // 6 - Commission bancaire (débit) [627]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '627',
                'intitule' => 'Remboursement internet CB',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => 0.00,
                'credit' => round($orderSlip->amount * 0.29 / 100, 2),
            ];

            // 7 - Commission bancaire (crédit) [4000018]
            $ret[] = [
                'date' => $orderSlipDate->format('d/m/Y'),
                'journal' => 'VE',
                'compte' => '4000018',
                'intitule' => 'Remboursement internet CB',
                'nofacture' => $this->orderInvoice->number . '-' . $orderSlip->id,
                'debit' => round($orderSlip->amount * 0.29 / 100, 2),
                'credit' => 0.00,
            ];
        }

        return $ret;
    }

    /**
     * @param OrderInvoice $orderInvoice
     * @param Order|null $order
     * @param OrderPayment[]|null $orderPayments
     * @param OrderSlip[]|null $orderSlips
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function __construct(
        OrderInvoice $orderInvoice,
        ?Order $order = null,
        ?array $orderPayments = null,
        ?array $orderSlips = null
    ) {
        $this->orderInvoice = $orderInvoice;
        if (!$order) {
            $this->order = new Order($orderInvoice->id_order);
        } else {
            $this->order = $order;
        }
        if (!$orderPayments) {
            $this->orderPayments = $this->order->getOrderPayments();
        } else {
            $this->orderPayments = $orderPayments;
        }
        $this->addressInvoice = new Address($this->order->id_address_invoice);

        if (!$orderSlips) {
            $result = OrderSlip::getOrdersSlip($this->order->id_customer, $orderInvoice->id_order);

            if (!is_array($result)) {
                $result = [];
            }

            $orderSlips = ObjectModel::hydrateCollection(
                OrderSlip::class, $result
            );

            if (count($orderSlips)) {
                /* @var OrderSlip[] orderSlips */
                $this->orderSlips = $orderSlips;
            }
        } else {
            $this->orderSlips = $orderSlips;
        }
    }

    public function isExportable(): bool
    {
        return !empty($this->orderInvoice->invoice_number);
    }

    public function hasSlip(): bool
    {
        return null !== $this->orderSlips && count($this->orderSlips) > 0;
    }

    /**
     * @param DateTimeInterface $dateDebut
     * @param DateTimeInterface $dateFin
     *
     * @return array<int|string,mixed>
     *
     * @throws Exception
     */
    public function getLignesComptables(DateTimeInterface $dateDebut, DateTimeInterface $dateFin): array
    {
        $ret = [];

        /// Export des lignes de la facture
        $invoiceDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $this->order->invoice_date);

        if ($invoiceDate >= $dateDebut && $invoiceDate <= $dateFin) {
            // Export OK
            $ret = array_merge($ret, $this->getLignesComptablesFacture());
        }

        /// Export des lignes du remboursement
        if ($this->orderSlips) {
            foreach ($this->orderSlips as $orderSlip) {
                $orderSlipDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $orderSlip->date_add);

                if ($orderSlipDate >= $dateDebut && $orderSlipDate <= $dateFin) {
                    // Export OK
                    $ret = array_merge($ret, $this->getLignesComptablesAvoir($orderSlip));
                }
            }
        }

        return $ret;
    }

    /**
     * Détermine si une série de lignes comptables sont cohérentes ou non
     *
     * Vérification effectuée : somme des crédits = sommes des débits (à 1ct près)
     *
     * @param array<string, mixed> $lignesComptables
     */
    public static function ensureCoherent(array $lignesComptables): bool
    {
        $sommes = array_reduce(
            $lignesComptables,
            function ($sommes, $ligne) {
                $sommes['credit'] += $ligne['credit'];
                $sommes['debit'] += $ligne['debit'];

                return $sommes;
            },
            [
                'credit' => 0.0,
                'debit' => 0.0,
            ]
        );

        return abs(round($sommes['credit'] - $sommes['debit'], 2)) <= 0.03;
    }

    /**
     * @return OrderInvoice
     */
    public function getOrderInvoice(): OrderInvoice
    {
        return $this->orderInvoice;
    }

    /**
     * @return Order
     */
    public function getOrder(): Order
    {
        return $this->order;
    }

    /**
     * @return OrderSlip[]|null
     */
    public function getOrderSlips(): ?array
    {
        return $this->orderSlips;
    }
}
