<?php

namespace Modules\Stock\Controller;

use DateTime;
use Entity\Model\CsDon;
use Entity\Model\Hastutil;
use Entity\Model\Memos;
use Entity\Model\Paravrac;
use Entity\Model\Sarticle;
use Entity\Model\SbsLign;
use Entity\Model\SbtLign;
use Entity\Model\SdsEnte;
use Entity\Model\SdsLign;
use Entity\Model\SdsPlan;
use Entity\Model\SSiteSto;
use Entity\Model\Sstocklo;
use Entity\Model\Tiers;
use Exception;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\ExportTo\Outils;
use Helpers\Filter\FiltreAvance\GeneratorCs;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Trad\Trad;
use Modules\Ajax\Repository\Listes;
use Modules\Stock\Enum\DemandeServiceTypeEnum;
use Modules\Stock\Enum\Operation;
use Modules\Stock\Enum\SoldeDemandeServiceEnum;
use Modules\Stock\Enum\TypeEnteteEnum;
use Modules\Stock\Helper\GestionFiltreHelper;
use Modules\Stock\MenuContextuel\DemandeServiceContextuel;
use Modules\Stock\MenuContextuel\LigneDemandeServiceContextuel;
use Modules\Stock\Repository\DemandeServiceRepo;
use Modules\Stock\Repository\LigneDemandeServiceRepo;
use Modules\Stock\Service\Export\DemandeServiceExportService;
use Modules\Stock\Service\Form\DemandeServiceFormService;
use Modules\Stock\Service\Form\LigneDemandeServiceFormService;
use Modules\Stock\Service\ListManagerService;
use Modules\Stock\Service\ParametrageService;
use Modules\Stock\Service\SoldeManuelService;
use Modules\Stock\Service\Validation\DemandeServiceValidationService;
use Modules\Stock\Trait\Controller\DemandeServiceControllerTrait;
use Modules\Stock\Trait\Controller\LigneDemandeServiceControllerTrait;
use Modules\Stock\Trait\Controller\StockContollerTrait;
use Modules\Stock\Trait\Controller\WebserviceTrait;
use Skeleton\Controller\Controller;

class DemandeServiceController extends Controller
{
    use WebserviceTrait;
    use StockContollerTrait;
    use DemandeServiceControllerTrait;
    use LigneDemandeServiceControllerTrait;

    /**
     * @throws Exception
     */
    public function gestionAction() : string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $currentUser = $this->getCurrentUser();
        $listManager = new ListManagerService($trad);

        GestionFiltreHelper::initialiseCodeSocieteFiltre($post, 'filter_SE#point#CODE_STE');
        if (Sql::toBool($currentUser['FILT_SIT'])) {
            GestionFiltreHelper::initialiseSiteStockFiltre($post, 'filter_egal_SE#point#SITE', $currentUser['SIT_STO']);
        }

        Ariane::generate(0, $trad->t('Gestion'), [], null, $this->router->generateUri('Stock.DemandeService.gestion'));

        (new PaginatorGestion())->generate(20, 'NO_DS');
        $demandesServices = (new DemandeServiceRepo($this->pdo))->listDemandesServices($post);
        $infoPagination = PaginatorGestion::getInfoPagination();

        (new DemandeServiceContextuel($this->pdo, $this->router, $trad))
            ->setDroits(['ST_DS_SMV' => Roles::droitsUtilisateur($this->pdo, 'ST_DS_SMV')])
            ->addMenuContextuelToEntities($demandesServices)
        ;

        $filtreAvance = new GeneratorCs($post, 'SDS_ENTE', 'SE.NO_DS', $this->pdo, $trad);
        $filtreAvance->setFiltre('SE.DTE_CREAT', 'date', $trad->t('Date création'));
        $filtreAvance->setFiltre('SE.DTE_VALID', 'date', $trad->t('Date validation'));
        $filtreAvance->setFiltre('SL.ART', 'liste', $trad->t('Code article'), '', 'Ajax.liste.stockArticles', 'Articles');

        return $this->renderer->render('@Stock/DemandeService/gestion', [
            'post'                    => $post,
            'menuActive'              => 'Stock',
            'infoPagination'          => $infoPagination,
            'demandesServices'        => $demandesServices,
            'initFiltreAvance'        => $filtreAvance->getInit(),
            'filtreAvance'            => $filtreAvance->getFiltres(),
            'listeFiltreEtat'         => $listManager->getDemandeServiceEtatsList(),
            'listeFiltreType'         => $listManager->getDemandeServiceTypesList(),
            'sessionFilters'          =>  json_encode([
                'filter_SE#point#CODE_STE' => $_SESSION['Session_SocUsr'],
                'filter_SL#point#ORIGINE'  => $_SESSION['SiteStock'],
            ]),
            'configAxeImp'            => (new Paravrac($this->pdo))->getCommandeAxeImpConfig()
        ]);
    }

    /**
     * @throws Exception
     */
    public function ligneAction(): string
    {
        $ssitesto = new SsiteSto($this->pdo);
        $trad = $this->getTranslationService();
        $noDs = $this->request->getAttribute('noDs');
        $demandeService = (new DemandeServiceRepo($this->pdo))->findFromNoDs($noDs);
        $siteStock = $ssitesto->find(['SITE' => $demandeService['SITE']], ['DESIGN']);
        $lignesDemandeService = (new LigneDemandeServiceRepo($this->pdo))->findAllFromNoDs($noDs);
        $destinataire = $demandeService['TYPE_DEM'] === DemandeServiceTypeEnum::S->name ? (new Tiers($this->pdo))->find(['CODE' => $demandeService['TIERS']], ['RS']): $ssitesto->find(['SITE' => $demandeService['TIERS']], ['DESIGN']);

        return $this->renderer->render('@Stock/DemandeService/ligne', [
            'id' => $noDs,
            'siteStock' => $siteStock,
            'destinataire' => $destinataire,
            'demandeService' => $demandeService,
            'lignesDemandeService' => $lignesDemandeService,
            'nombreEnregistrement' => count($lignesDemandeService),
            'listeFiltreEtat'   => (new ListManagerService($trad))->getDemandeServiceEtatsList(),
        ]);
    }

    /**
     * @throws Exception
     */
    public function nouvelleAction(): string|Response
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $dateCreation = new DateTime('now');

        Ariane::generate(
            1,
            $trad->t('Création de demande de service'),
            [],
            null,
            $this->router->generateUri('Stock.DemandeService.nouvelle')
        );

        $demandeServiceFormService = new DemandeServiceFormService($this->pdo);
        $siteStock = (new SSiteSto($this->pdo))->find(['SITE' => $post['SITE']]);

        if ($this->request->getMethod() === 'POST') {
            $listes = new Listes($this->pdo);
            $validator = $this->getDemandeServiceValidator();
            $sitesStockAccessibles = array_column($listes->listSitesStockAccessibles([], false), null, 'SITE');
            $parametreNumerotation = (new ParametrageService($this->pdo))->getParametreNumerotation(TypeEnteteEnum::DS, $siteStock['CODE_STE'] ?? null);

            $validator
                ->validateTypeDemande($post)
                ->validateDateCreation($post)
                ->validateSiteOrigine($post, $siteStock)
                ->validateSiteDestinataire($post, $sitesStockAccessibles)
                ->validateNo($post, $parametreNumerotation, TypeEnteteEnum::DS, 'demande de service');

            if ($validator->isNonBloquant() && !isset($post['confirm'])) {
                return $this->createNonBloquantJsonErrorResponse(
                    'Confirmez-vous la création de cette demande de service',
                    $validator->getErrorNonBloquant(),
                    $parametreNumerotation
                );
            }

            if ($validator->isValid(true)) {
                $demandeService = $demandeServiceFormService->initEntity($post, ['SITE_ORIGINE' => $siteStock, 'PARAMETRE_NUMEROTATION' => $parametreNumerotation]);

                $this->pdo->beginTransaction();
                $demandeServiceFormService->flushData($demandeService, ['PARAMETRE_NUMEROTATION' => $parametreNumerotation, 'operation' => Operation::CREATE]);
                $this->getPdo()->commit();

                return $this->createJsonResponse(['statut' => 'OK', 'redirectRoute' => $this->router->generateUri(
                    'Stock.DemandeService.modifier',
                    ['noDs' => $demandeService['NO_DS']]
                )]);
            } else {
                return $this->createBloquantJsonErrorResponse($parametreNumerotation, $validator->getError());
            }
        }

        $currentUser = (new Hastutil($this->pdo))->find($_SESSION["Session_Login"], ['CODE_STE']);
        $parametreNumerotation = (new ParametrageService($this->pdo))->getParametreNumerotation(TypeEnteteEnum::DS, $currentUser['CODE_STE']);

        return $this->renderer->render('@Stock/DemandeService/nouvelle', [
            'post' => $post,
            'dateJour' => date("Ymd"),
            'parametreNumerotation' => $parametreNumerotation,
            'dateCreation' => $dateCreation->format('d/m/Y'),
            'listeFiltreType' => (new ListManagerService($trad))->getDemandeServiceTypesList(),
        ]);
    }

    /**
     * @throws Exception
     */
    public function modifierAction(): string|Response
    {
        $sqlMemo = new Sql();
        $memos = new Memos($this->pdo);
        $sdsEnte = new SdsEnte($this->pdo);
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $noDs = $this->request->getAttribute('noDs');
        $demandeService = (new DemandeServiceRepo($this->pdo))->findDemandeService($noDs);
        $lignesDemandeService = (new LigneDemandeServiceRepo($this->pdo))->findAllFromNoDs($noDs);
        $noLigne = (new LigneDemandeServiceRepo($this->pdo))->getNouveauNoLigne($noDs, 'NO_LIG_DS', 'SDS_LIGN', 'NO_DS');

        if (!$demandeService) {
            return $this->create404Response(Trad::strBuild($trad->t('La demande de service portant le numéro @1@ n\'existe pas'), $noDs));
        }
        
        Ariane::generate(0, $trad->t('Gestion'), [], null, $this->router->generateUri('Stock.DemandeService.gestion'));

        Ariane::generate(
            1,
            $trad->t('Modification de demande de service'),
            [],
            null,
            $this->router->generateUri('Stock.DemandeService.modifier', ['noDs' => $noDs])
        );

        if ($this->request->getMethod() === 'POST') {
            $validator = $this->getDemandeServiceValidator();
            $demandeService = array_merge($demandeService, $post['SDS_ENTE']);
            $sitesStockAccessibles = array_column((new Listes($this->pdo))->listSitesStockAccessibles([], false), null, 'SITE');

            $validator
                ->validateCommentaire($demandeService)
                ->validateSiteDestinataire($demandeService, $sitesStockAccessibles, true)
                ->validateCs('SDS_ENTE', [$demandeService['NO_DS'], null], $post)
            ;

            if ($validator->isValid()) {
                $this->pdo->beginTransaction();

                /** Enregistrement ou mise à jour du commentaire en bdd */
                $nodeMemo = (int) $demandeService['NM_COMME'] === 0 ? $sqlMemo->generateNum($this->pdo): $demandeService['NM_COMME'];
                $demandeService['NM_COMME'] = (string) $nodeMemo;
                $memo = ['NODEMEMO' => $nodeMemo, 'CONTMEMO' => $demandeService['COMMENTAIRE']];
                $memos->merge($memo);

                /** Enregistrement ou mise à jour de sdsEnt en bdd */
                unset($demandeService['SO_DESIGN']);
                unset($demandeService['COMMENTAIRE']);
                unset($demandeService['DEST_DESIGN']);
                unset($demandeService['SOC_DESIGN']);
                unset($demandeService['CS1']);
                unset($demandeService['CS2']);
                $sdsEnte->merge($demandeService);

                /** Mise à jour des valeurs des CS */
                ChampSupp::updateCS($post, $this->pdo);

                $this->pdo->commit();

                return $this->createJsonResponse($this->getSuccessDataWithValidation(
                    'ST_DS_VAL',
                    ['noDs' => $noDs],
                    'DemandeService',
                    'Voulez vous valider cette demande de service ?'
                ));
            } else {
                return $this->createBloquantJsonErrorResponse($demandeService, $validator->getError());
            }
        }

        $menuContextuel = new LigneDemandeServiceContextuel($this->pdo, $this->router, $trad);

        foreach ($lignesDemandeService as $key => $ligneDemandeService) {
            $lignesDemandeService[$key]['DELETE_POPUP'] = $menuContextuel->getDeletePopupConfirm($ligneDemandeService['NO_DS'], $ligneDemandeService['NO_LIG_DS']);
        }

        return $this->renderer->render('@Stock/DemandeService/modifier', [
            'post' => $post,
            'noDs' => $noDs,
            'noLigne' => $noLigne,
            'typeEntete' => TypeEnteteEnum::DS,
            'demandeService' => $demandeService,
            'lignesDemandeService' => $lignesDemandeService,
            'configAxeImp' => (new Paravrac($this->pdo))->getCommandeAxeImpConfig($demandeService['CODE_STE'])
        ]);
    }

    /**
     * @throws Exception
     */
    public function visualiserAction(): string
    {
        $trad = $this->getTranslationService();
        $noDs = $this->request->getAttribute('noDs');
        $demandeService = (new DemandeServiceRepo($this->pdo))->findDemandeService($noDs);
        $lignesDemandeService = (new LigneDemandeServiceRepo($this->pdo))->findAllFromNoDs($noDs);

        Ariane::generate(
            1,
            $trad->t('Visualisation demande de service'),
            [],
            null,
            $this->router->generateUri('Stock.DemandeService.visualiser', ['noDs' => $noDs])
        );

        return $this->renderer->render('@Stock/DemandeService/visualiser', [
            'noDs' => $noDs,
            'demandeService' => $demandeService,
            'lignesDemandeService' => $lignesDemandeService
        ]);
    }

    /**
     * @throws Exception
     */
    public function supprimerAction(): Response
    {
        $csDon = new CsDon($this->pdo);
        $sdsPlan = new SdsPlan($this->pdo);
        $sdsLign = new SdsLign($this->pdo);
        $sdsEnte = new SdsEnte($this->pdo);
        $noDs = $this->request->getAttribute('noDs');

        if (!$demandeService = $sdsEnte->find(['NO_DS' => $noDs])) {
            return $this->createJsonResponse([
                'statut' => 'Not found',
                'message' => 'La demande de service N° '.$noDs.' n\'existe pas'
            ], 404);
        }

        $codeEnrDemandeService = ChampSupp::autoCompletCodeEnr($noDs, null, 'SDS_ENTE');
        $lignesDemandeService = (new LigneDemandeServiceRepo($this->pdo))->findAllFromNoDs($noDs);

        $this->pdo->beginTransaction();

        foreach ($lignesDemandeService as $ligneDemandeService) {
            $codeEnrLigneDemandeService = ChampSupp::autoCompletCodeEnr($noDs, $ligneDemandeService['NO_LIG_DS'], 'SDS_ENTE');
            $sdsPlan->delete(['NO_DS' => $noDs, 'NO_LIG_DS' => $ligneDemandeService['NO_LIG_DS']]);
            $csDon->delete(['COD_TAB' => 'SDS_LIGN', 'COD_ENR' => $codeEnrLigneDemandeService]);
            $sdsLign->delete(['NO_DS' => $noDs, 'NO_LIG_DS' => $ligneDemandeService['NO_LIG_DS']]);
        }

        $sdsEnte->delete(['NO_DS' => $noDs]);
        $csDon->delete(['COD_TAB' => 'SDS_ENTE', 'COD_ENR' => $codeEnrDemandeService]);
        (new Memos($this->pdo))->delete(['NODEMEMO' => $demandeService['NM_COMME']]);

        $this->pdo->commit();

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @throws Exception
     */
    public function dupliquerFormAction(): string
    {
        $trad = $this->getTranslationService();
        $dateCreation = new DateTime('now');
        $noDs = $this->request->getAttribute('noDs');
        $listManagerService = new ListManagerService($trad);
        $demandeService = (new DemandeServiceRepo($this->pdo))->findDemandeService($noDs);
        $parametreNumerotation = (new ParametrageService($this->pdo))->getParametreNumerotation(TypeEnteteEnum::DS, $demandeService['CODE_STE']);

        Ariane::generate(
            1,
            $trad->t('Duplication de demande de service'),
            [],
            null,
            $this->router->generateUri('Stock.DemandeService.dupliquer', ['noDs' => $noDs])
        );

        return $this->renderer->render('@Stock/DemandeService/dupliquer', [
            'dateJour' => date("Ymd"),
            'demandeService' => $demandeService,
            'parametreNumerotation' => $parametreNumerotation,
            'dateCreation' => $dateCreation->format('d/m/Y'),
            'listeFiltreEtat' => $listManagerService->getDemandeServiceEtatsList(),
            'listeFiltreType' => $listManagerService->getDemandeServiceTypesList(),
        ]);
    }

    /**
     * @throws Exception
     */
    public function dupliquerAction(): Response
    {
        $listes = new Listes($this->pdo);
        $post = $this->request->getParsedBody();
        $validator = $this->getDemandeServiceValidator();
        $siteStock = (new SSiteSto($this->pdo))->find(['SITE' => $post['SITE']]);
        $parametreNumerotation = (new ParametrageService($this->pdo))->getParametreNumerotation(TypeEnteteEnum::DS, $post['CODE_STE']);
        $sitesStockAccessibles = array_column($listes->listSitesStockAccessibles([], false), null, 'SITE');

        $validator
            ->validateTypeDemande($post)
            ->validateDateCreation($post)
            ->validateSiteOrigine($post, $siteStock)
            ->validateSiteDestinataire($post, $sitesStockAccessibles)
            ->validateNo($post, $parametreNumerotation, TypeEnteteEnum::DS, 'demande de service')
        ;

        if ($validator->isNonBloquant() && !isset($post['confirm'])) {
            return $this->createNonBloquantJsonErrorResponse('Confirmez-vous la duplication de cette demande de service', $validator->getErrorNonBloquant(), $parametreNumerotation);
        }

        if ($validator->isValid(true)) {
            $sdsPlan = new SdsPlan($this->pdo);
            $sdsLign = new SdsLign($this->pdo);
            $demandeServiceFormService = new DemandeServiceFormService($this->pdo);
            $ligneDemandeServiceFormService = new LigneDemandeServiceFormService($this->pdo);
            $lignesDemandeService = $sdsLign->findAll(['NO_DS' => $post['NO_DS_A_DUPLIQUER']]);
            $demandeService = $demandeServiceFormService->initEntity($post, ['SITE_ORIGINE' => $siteStock, 'PARAMETRE_NUMEROTATION' => $parametreNumerotation]);

            $this->pdo->beginTransaction();

            $demandeServiceFormService->duplicateMemos($demandeService);
            $demandeServiceFormService->flushData($demandeService);
            $demandeServiceFormService->duplicateCS($post['NO_DS_A_DUPLIQUER'], $demandeService['NO_DS'], null, 'SDS_ENTE');

            foreach ($lignesDemandeService as $ligneDemandeService) {
                /**  Duplication des SDS_LIGN */
                $lignesPlanning = $sdsPlan->findAll(['NO_DS' => $post['NO_DS_A_DUPLIQUER'], 'NO_LIG_DS' => $ligneDemandeService['NO_LIG_DS']]);
                $ligneDemandeService = $ligneDemandeServiceFormService->initEntity($ligneDemandeService, ['DEMANDE_SERVICE' => $demandeService]);
                $ligneDemandeServiceFormService->gererCodgestPropriete($ligneDemandeService);
                $sdsLign->insert($ligneDemandeService);

                /**  Duplication des SDS_PLAN */
                foreach ($lignesPlanning as $lignePlanning) {
                    $lignePlanning['NO_DS'] = $ligneDemandeService['NO_DS'];
                    $lignePlanning['NO_LIG_DS'] = $ligneDemandeService['NO_LIG_DS'];
                    $lignePlanning['REAPPRO_FAIT'] = Sql::toBool($lignePlanning['REAPPRO_FAIT']);
                    $sdsPlan->insert($lignePlanning);
                }

                /** Duplication des CS_DON de la SDS_LIGN */
                $demandeServiceFormService->duplicateCS($post['NO_DS_A_DUPLIQUER'], $demandeService['NO_DS'], $ligneDemandeService['NO_LIG_DS'], 'SDS_LIGN');
            }

            $this->getPdo()->commit();

            return $this->createJsonResponse([
                'statut' => 'OK',
                'redirectRoute' => $this->router->generateUri('Stock.DemandeService.modifier', ['noDs' => $demandeService['NO_DS']])
            ]);
        } else {
            return $this->createBloquantJsonErrorResponse($parametreNumerotation, $validator->getError());
        }
    }

    /**
     * @throws Exception
     */
    public function validerAction(): Response
    {
        $sdsEnte = new SdsEnte($this->pdo);
        $post = $this->request->getParsedBody();
        $noDs = $this->request->getAttribute('noDs');
        $demandeService = $sdsEnte->find($noDs);
        $trad = $this->getTranslationService();
        $lignesDemandeService = (new SdsLign($this->pdo))->findAll(['NO_DS' => $demandeService['NO_DS']], [], ['tri_NO_LIG_DS' => 'ASC']);

        if ($demandeService['SOLDE_DS'] !== SoldeDemandeServiceEnum::A->name) {
            return $this->createJsonResponse(['statut' => 'Forbidden'], 403);
        }

        $demandeServiceValidationService = (new DemandeServiceValidationService($this->pdo, $trad))->validate($demandeService, $lignesDemandeService);

        if ($demandeServiceValidationService->isNonBloquant() && !isset($post['confirm'])) {
            return $this->createJsonResponse([
                'post' => $post,
                'type' => 'nonBloquant',
                'popupTitle' => $trad->t('Confirmez-vous la validation de cette demande de service ?'),
                'popupHtml' => $this->renderer->render('@Stock/Composant/_validation_erreurs', [
                    'type' => 'nonBloquant',
                    'errors' => $demandeServiceValidationService->getErrors()
                ])
            ], 400);
        }
        if (!$demandeServiceValidationService->isValid()) {
            return $this->createJsonResponse([
                'type' => 'bloquant',
                'popupTitle' => $trad->t('Cette demande de service ne peut pas être dévalidée'),
                'popupHtml' => $this->renderer->render('@Stock/Composant/_validation_erreurs', [
                    'type' => 'bloquant',
                    'errors' => $demandeServiceValidationService->getErrors()
                ])
            ], 400);
        }

        $demandeServiceValidationService->save($demandeService, $lignesDemandeService);

        return $this->createJsonResponse(['statut' => 'OK', 'redirectRoute' => $this->router->generateUri('Stock.DemandeService.gestion')]);
    }

    /**
     * @throws Exception
     */
    public function devaliderAction(): Response
    {
        $sdsLign = new SdsLign($this->pdo);
        $sdsEnte = new SdsEnte($this->pdo);
        $sstocklo = new Sstocklo($this->pdo);
        $sarticle = new Sarticle($this->pdo);
        $trad = $this->getTranslationService();
        $noDs = $this->request->getAttribute('noDs');
        $demandeService = $sdsEnte->find(['NO_DS' => $noDs]);

        if ($demandeService['SOLDE_DS'] !== SoldeDemandeServiceEnum::E->name && $demandeService['SOLDE_DS'] !== SoldeDemandeServiceEnum::S->name) {
            return $this->createJsonResponse([
                'statut' => 'Forbidden',
                'popupTitle' => $trad->t('Action non autorisée'),
                'popupContent' => $trad->t('Cette demande de service ne peut pas être dévalidée')
            ], 403);
        }

        $linkedLignes = match ($demandeService['TYPE_DEM']) {
            DemandeServiceTypeEnum::S->name => (new SbsLign($this->pdo))->findAll(['NO_DS' => $noDs]),
            DemandeServiceTypeEnum::T->name => (new SbtLign($this->pdo))->findAll(['NO_DS' => $noDs]),
            default => []
        };

        if (!empty($linkedLignes)) {
            return $this->createJsonResponse([
                'statut' => 'Error',
                'popupTitle' => $trad->t('Impossible de dévalider cette demande de service'),
                'popupContent' => $trad->t('Les demandes de services liées à des bons de sortie ou
                à des bons de transfert ne peuvent pas être dévalidées')
            ], 400);
        }

        $lignesDemandeService = (new SdsLign($this->pdo))->findAll(['NO_DS' => $demandeService['NO_DS']]);

        $this->pdo->beginTransaction();

        $demandeService['SOLDE_DS'] = SoldeDemandeServiceEnum::A->name;
        $demandeService['DTE_VALID'] = '00000000';
        $sdsEnte->merge($demandeService);

        foreach ($lignesDemandeService as $ligneDemandeService) {
            DemandeServiceValidationService::updateLigneDemandeService($sdsLign, $ligneDemandeService, false);
            DemandeServiceValidationService::updateStockLocal($sstocklo, $demandeService, $ligneDemandeService, false);
            DemandeServiceValidationService::updateStockArticle($sarticle, $demandeService, $ligneDemandeService, false);
        }

        $this->pdo->commit();

        return $this->createJsonResponse(['statut' => 'OK', 'redirectRoute' => $this->router->generateUri('Stock.DemandeService.gestion')]);
    }

    public function popupExportAction() : string
    {
        $tables = ['Entête' => 'SDS_ENTE', 'Ligne' => 'SDS_LIGN'];
        $tab = (new DemandeServiceExportService($this->pdo, $this->getTranslationService()))->getTab($tables);
        asort($tab);

        return $this->renderer->render('@GlobalApplication/Popup/popupExport', [
            'pathExport' => $this->router->generateUri('Stock.DemandeService.exporter'),
            'formFilter' => 'filtres-demandes-de-service',
            'coloneExport' => $tab,
            'tabObli' => ['SE.NO_DS', 'SL.NO_LIG_DS'],
            'post' => [
                'multiSelectexportFacOBLI1' => 'SE.NO_DS',
                'multiSelectexportFacOBLI2' => 'SL.NO_LIG_DS',
            ],
        ]);
    }

    /**
     * @throws Exception
     */
    public function exporterAction(): Response
    {
        $post = $this->request->getParsedBody();
        $postFilters = !empty($this->request->getParsedBody()['okFilter']) ? $post: [];
        $demandeServiceExportService = new DemandeServiceExportService($this->pdo, $this->getTranslationService());

        $arrayMultiSelect = $demandeServiceExportService->getArrayMultiSelect($post);
        $listeCS = $demandeServiceExportService->getListeCS($arrayMultiSelect);

        $demandesServices = (new DemandeServiceRepo($this->pdo))->listDemandesServicesExport($postFilters, implode(',', $arrayMultiSelect));

        $entete = $demandeServiceExportService->getTableEntete($arrayMultiSelect, $listeCS, 'SDS_ENTE', 'SDS_LIGN');
        $champsDate = $demandeServiceExportService->getChampsParType('DATE');

        foreach ($demandesServices as &$demandeService) {
            /** @var array<int,array<string,string>> $listeCS */
            $demandeServiceExportService->addChampsSupplementaireValeur($listeCS, $demandeService, 'NO_DS', 'NO_LIG_DS', 'SDS_LIGN');
            $demandeServiceExportService->convertirDates($champsDate, $demandeService);
        }

        Outils::gestionEmailAsync2(
            'export_DS_'.date('Ymd'),
            $demandesServices,
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $entete
        );

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @return Response
     * @throws Exception
     */
    public function soldeManuelAction(): Response
    {
        (new SoldeManuelService($this->pdo))->process($this->request->getAttribute('noDs'), SoldeDemandeServiceEnum::S);

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @return Response
     * @throws Exception
     */
    public function desoldeManuelAction(): Response
    {
        (new SoldeManuelService($this->pdo))->process($this->request->getAttribute('noDs'), SoldeDemandeServiceEnum::E);

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @throws Exception
     */
    public function imprimerAction(): string|Response
    {
        $noDs = $this->request->getAttribute('noDs');
        $xml = '<DSIn LngUtilisation="'.htmlspecialchars($_SESSION['Session_Langue']).'">
                    <Utilisateur>'.$_SESSION['Session_Login'].'</Utilisateur>
                    <NumeroDS>'.$noDs.'</NumeroDS>
                </DSIn>';

        return $this->webserviceImpressionResponse($xml, 'OXAPRC_IMPRIMEDS', 'Demande_de_service_'.$noDs);
    }
}
