src/Services/EfacApiService.php line 250

Open in your IDE?
  1. <?php
  2. /**
  3.  * Created by PhpStorm.
  4.  */
  5. namespace App\Services;
  6. use App\Entity\Avoir;
  7. use App\Entity\AvoirMontantTva;
  8. use App\Entity\DocUpload;
  9. use App\Entity\EfacAuth;
  10. use App\Entity\EfacData;
  11. use App\Entity\Entreprise;
  12. use App\Entity\FactureFinance;
  13. use App\Entity\FactureFinanceMontantTva;
  14. use App\Entity\Fournisseur;
  15. use App\Entity\Project;
  16. use App\Entity\ProjectAvoir;
  17. use App\Entity\ProjectFactureFinance;
  18. use App\Entity\Spv;
  19. use App\Form\CentraleType;
  20. use App\Form\EntrepriseType;
  21. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  22. use Doctrine\ORM\EntityManagerInterface;
  23. use Symfony\Component\Form\FormFactoryInterface;
  24. use Symfony\Component\HttpFoundation\Response;
  25. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  26. use Symfony\Contracts\Translation\TranslatorInterface;
  27. use Symfony\Component\Security\Core\Security;
  28. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  29. use Twig\Environment;
  30. use App\Entity\Centrale;
  31. use Symfony\Component\Validator\Constraints as Assert;
  32. use Symfony\Component\Validator\Validator\ValidatorInterface;
  33. use Symfony\Component\Validator\Validation;
  34. use Symfony\Component\HttpClient\HttpClient;
  35. class EfacApiService
  36. {
  37.     private $em;
  38.     private $params;
  39.     public function __construct(
  40.         ParameterBagInterface $params,
  41.         EntityManagerInterface $em,
  42.         Notifications $notifications
  43.     ) {
  44.         $this->em = $em;
  45.         $this->params = $params;
  46.         $this->notification = $notifications;
  47.     }
  48.     public function authApiEfac($publicKey,$secretKey){
  49.         if (!$publicKey || !$secretKey) {
  50.             return ['error' => 'Clés manquantes' , 'status'=> Response::HTTP_UNAUTHORIZED];
  51.         }
  52.         $client = $this->em->getRepository(EfacAuth::class)->findOneBy(['publicKey' => $publicKey]);
  53.         if (!$client) {
  54.             return ['error' => 'Clé publique invalide' , 'status'=> Response::HTTP_FORBIDDEN];
  55.         }
  56.         if ($client && $client->getSecretKey() !== $secretKey ) {
  57.             return ['error' => 'Clé secrète invalide' , 'status'=> Response::HTTP_FORBIDDEN];
  58.         }
  59.         if ($client && !$client->getIsEnabled() ) {
  60.             return ['error' => 'Accès non activés' , 'status'=> Response::HTTP_FORBIDDEN];
  61.         }
  62.         return ['message' => 'Accès autorisé' , 'status'=> Response::HTTP_OK];
  63.     }
  64.     public function getTypeDocument($type){
  65.         if(in_array($type,[EfacData::document_facture_affacturee,
  66.                            EfacData::document_facture_auto_facturee,
  67.                            EfacData::document_facture_auto_facturee_affacturee,
  68.                            EfacData::document_facture_commercial,
  69.                            EfacData::document_facture_rectificative,
  70.                            EfacData::document_facture_rectificative_affacturee,
  71.                            EfacData::document_facture_rectificative_auto_facturee_affacturee,
  72.                            EfacData::document_facture_rectificative_auto_facturee
  73.         ])){
  74.             return EfacData::type_facture;
  75.         }
  76.         elseif (in_array($type,[EfacData::document_acompte_facture,EfacData::document_acompte_auto_facture])){
  77.             return EfacData::type_acompte;
  78.         }elseif  (in_array($type,[EfacData::document_avoir,
  79.                                   EfacData::document_avoir_affacturee,
  80.                                   EfacData::document_avoir_auto_facture,
  81.                                   EfacData::document_avoir_auto_facture_affacturee,
  82.                                   EfacData::document_avoir_facture_acompte,
  83.                                   EfacData::document_avoir_remise_globale
  84.             ])){
  85.             return EfacData::type_avoir;
  86.         }else{
  87.             return null;
  88.         }
  89.     }
  90.     public function addFactureOrAvoir($request){
  91.         $data = json_decode($request->getContent(), true);
  92.         if (!$data) {
  93.             $this->addEfacDataLog('',$request->getContent(),'JSON invalide');
  94.             return ['error' => 'JSON invalide' , 'status'=> Response::HTTP_BAD_REQUEST];
  95.         }
  96.         //check field blanc date number choice
  97.         $validator = Validation::createValidator();
  98.         $constraint = new Assert\Collection([
  99.             'documentList' => [
  100.                 new Assert\NotBlank(),
  101.                 new Assert\Type('array'),
  102.                 new Assert\Count(['min' => 1]),
  103.                 new Assert\All([
  104.                     new Assert\Collection([
  105.                         'invoice_document_type' => [new Assert\NotBlank()],
  106.                         'invoice_international' => [new Assert\NotBlank(), new Assert\Choice(['0', '1'])],
  107.                         'invoice_status' => [new Assert\NotBlank(), new Assert\Choice(['Accepté', 'Rejeté'])],
  108.                         'invoice_number_efac' => [new Assert\NotBlank()],
  109.                         'invoice_number_fournisseur' => [new Assert\NotBlank()],
  110.                         'invoice_issue_date' => [new Assert\NotBlank(), new Assert\Date()],
  111.                         'invoice_due_date' => [new Assert\NotBlank(), new Assert\Date()],
  112.                         'invoice_supplier' => [new Assert\NotBlank()],
  113.                         'invoice_spv' => [new Assert\NotBlank()],
  114.                         'invoice_validation_history' => [new Assert\NotBlank()],
  115.                         'invoice_link' => [new Assert\NotBlank(), new Assert\Url()],
  116.                         'invoice_pa_id' => [new Assert\NotBlank()],
  117.                         'currency' => [new Assert\NotBlank()],
  118.                         // Lignes
  119.                         'line' => [
  120.                             new Assert\NotBlank(),
  121.                             new Assert\Type('array'),
  122.                             new Assert\Count(['min' => 1]),
  123.                             new Assert\All([
  124.                                 new Assert\Collection([
  125.                                     'unitPrice' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  126.                                     'number' => [new Assert\NotBlank(), new Assert\Type('integer')],
  127.                                     'note' => [new Assert\NotBlank()],
  128.                                     'unit' => [new Assert\NotBlank()],
  129.                                     'amount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  130.                                     'quantity' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  131.                                     'vatType' => [new Assert\NotBlank()],
  132.                                     'vatRate' => [new Assert\NotBlank(), new Assert\Type('numeric')]
  133.                                 ])
  134.                             ])
  135.                         ],
  136.                         // Total
  137.                         'total' => [
  138.                             new Assert\NotBlank(),
  139.                             new Assert\Collection([
  140.                                 'accountingCurrency' => [new Assert\NotBlank()],
  141.                                 'amount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  142.                                 'netPayable' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  143.                                 'netAmount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  144.                                 'reductionAmount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  145.                                 'costAmount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  146.                                 'amountIncludingTax' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  147.                                 'vatAmount' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  148.                             ])
  149.                         ],
  150.                     ])
  151.                 ])
  152.             ],
  153.             'count' => [new Assert\NotBlank(), new Assert\Type('integer')],
  154.             'transactionId' => [new Assert\NotBlank()]
  155.         ]);
  156.         $violations = $validator->validate($data, $constraint);
  157.         if (count($violations) > 0) {
  158.             $errors = [];
  159.             foreach ($violations as $violation) {
  160.                 $errors[] = [
  161.                     'field' => $violation->getPropertyPath(),
  162.                     'message' => $violation->getMessage()
  163.                 ];
  164.             }
  165.             $this->addEfacDataLog($data['transactionId'],$request->getContent(),json_encode($errors));
  166.             return ['errors' => $errors , 'status'=> Response::HTTP_BAD_REQUEST];
  167.         }else{
  168.             $errors = [];
  169.             //check field data base de donnée
  170.             foreach ($data['documentList'] as $key=>&$datum){
  171.                 $typeDoc = $this->getTypeDocument($datum['invoice_document_type']);
  172.                 $numero = $datum['invoice_pa_id'];
  173.                 $codeFournisseur = $datum['invoice_supplier'];
  174.                 $codeSpv = $datum['invoice_spv'];
  175.                 if($typeDoc == EfacData::type_facture || $typeDoc == EfacData::type_acompte){
  176.                     $facture = $this->em->getRepository(FactureFinance::class)->findOneBy(['invoicePaId'=>$numero]);
  177.                     if($facture){
  178.                         $errors[] = [
  179.                             'field' => "[documentList][$key][invoice_pa_id]",
  180.                             'message' => "Ce numéro de facture existe déjà."
  181.                         ];
  182.                     }
  183.                 }elseif($typeDoc == EfacData::type_avoir){
  184.                     $avoir = $this->em->getRepository(Avoir::class)->findOneBy(['invoicePaId'=>$numero]);
  185.                     if($avoir){
  186.                         $errors[] = [
  187.                             'field' => "[documentList][$key][invoice_pa_id]",
  188.                             'message' => "Ce numéro d’avoir existe déjà."
  189.                         ];
  190.                     }
  191.                 }
  192.                 $spv = $this->em->getRepository(Spv::class)->findOneBy(['codeSage'=>$codeSpv]);
  193.                 $fournisseur = $this->em->getRepository(Fournisseur::class)->findNotArchiveByCodeSingle($codeFournisseur);
  194.                 if(!$spv){
  195.                     $errors[] = [
  196.                         'field' => "[documentList][$key][invoice_spv]",
  197.                         'message' => "Le code ne correspond à aucune SPV."
  198.                     ];
  199.                 }
  200.                 if(!$fournisseur){
  201.                     $errors[] = [
  202.                         'field' => "[documentList][$key][invoice_supplier]",
  203.                         'message' => "Le code ne correspond à aucun fournisseur."
  204.                     ];
  205.                 }
  206.                 $datum['spv'] = $spv;
  207.                 $datum['fournisseur'] = $fournisseur;
  208. //                $client = HttpClient::create();
  209. //                $response = $client->request('GET', $datum['invoice_link']);
  210. //                if ($response->getStatusCode() !== 200) {
  211. //                    $errors[] = [
  212. //                        'field' => "[documentList][$key][invoice_link]",
  213. //                        'message' => "URL de fichier erronée"
  214. //                    ];
  215. //                }
  216.             }
  217.             if (count($errors) > 0) {
  218.                 $this->addEfacDataLog($data['transactionId'],$request->getContent(),json_encode($errors));
  219.                 return ['errors' => $errors , 'status'=> Response::HTTP_CONFLICT];
  220.             }else{
  221.                 foreach ($data['documentList'] as $key=>$datum){
  222.                     $typeDoc = $this->getTypeDocument($datum['invoice_document_type']);
  223.                     if($typeDoc == EfacData::type_facture || $typeDoc == EfacData::type_acompte){
  224.                         $this->addFacture($datum);
  225.                     }elseif($typeDoc == EfacData::type_avoir){
  226.                         $this->addAvoir($datum);
  227.                     }
  228.                 }
  229.                 $this->addEfacDataLog($data['transactionId'],$request->getContent(),Response::HTTP_OK);
  230.                 return ['message' => 'Facture reçue et enregistrée' , 'status'=> Response::HTTP_OK];
  231.             }
  232.         }
  233.         return ['errors' => 'Requête invalide' , 'status'=> Response::HTTP_BAD_REQUEST];
  234.     }
  235.     public function addEfacDataLog($transactionId="",$data,$msg){
  236.         $dataLog = new EfacData();
  237.         $dataLog->setDataEfac($data);
  238.         $dataLog->setMsg($msg);
  239.         $dataLog->setTransactionId($transactionId);
  240.         $this->em->persist($dataLog);
  241.         $this->em->flush();
  242.     }
  243.     public function addFacture($data){
  244.         $typeDoc = $this->getTypeDocument($data['invoice_document_type']);
  245.         if($typeDoc == EfacData::type_acompte){
  246.             $type = 'Acompte';
  247.         }else{
  248.             $type = 'Facture';
  249.         }
  250.         $facture = new FactureFinance();
  251.         $facture->setIsRfe(true);
  252.         $facture->setNumeroFacture($data['invoice_number_fournisseur']);
  253.         $facture->setCategory($type);
  254.         $facture->setFournisseur($data['fournisseur']);
  255.         $facture->setSpv($data['spv']);
  256.         $facture->setDateFacture(new \DateTime($data['invoice_issue_date']));
  257.         $facture->setDelaiPaiementDate(new \DateTime($data['invoice_due_date']));
  258.         $facture->setDelaiPaiement((new \DateTime($data['invoice_due_date']))->diff(new \DateTime($data['invoice_issue_date']))->days);
  259. //        $doc = $this->importPdf($data['invoice_link']);
  260. //        if($doc){
  261. //            $facture->setFileFacture($doc);
  262. //        }
  263.         $facture->setUrlFacture($data['invoice_link']);
  264.         $facture->setStatus(FactureFinance::STATUS_A_COMPLETER);
  265.         $facture->setInvoiceDocumentType($data['invoice_document_type']);
  266.         $facture->setInvoiceCurrency($data['currency']);
  267.         $facture->setInvoiceInternational($data['invoice_international']);
  268.         $facture->setInvoiceStatus($data['invoice_status']);
  269.         $facture->setInvoiceNumberEfac($data['invoice_number_efac']);
  270.         $facture->setInvoicePaId($data['invoice_pa_id']);
  271.         $this->em->persist($facture);
  272.         $this->em->flush();
  273.         $facture->setTauxTva(0);
  274.         foreach ($data['line'] as $line){
  275.             $nbrDivision = 100;
  276.             $factureFinanceMantant = new FactureFinanceMontantTva();
  277.             $factureFinanceMantant->setFactureFinance($facture);
  278.             $factureFinanceMantant->setUnitPrice($line['unitPrice']/$nbrDivision);
  279.             $factureFinanceMantant->setNumber($line['number']);
  280.             $factureFinanceMantant->setNote($line['note']);
  281.             $factureFinanceMantant->setUnit($line['unit']);
  282.             $factureFinanceMantant->setMontantHt($line['amount']/$nbrDivision);
  283.             $factureFinanceMantant->setQuantity($line['quantity']);
  284.             $factureFinanceMantant->setVatType($line['vatType']);
  285.             $factureFinanceMantant->setTauxTva($line['vatRate']);
  286.             $montantTva = (($line['amount']/$nbrDivision) * $line['vatRate']) / 100 ;
  287.             if(in_array($line['vatType'],["E","AE","K","G","O","Z"])){
  288.                 $factureFinanceMantant->setMontantTtc($line['amount']/$nbrDivision);
  289.             }else{
  290.                 $montantTtc = $montantTva + ($line['amount']/$nbrDivision);
  291.                 $factureFinanceMantant->setMontantTtc($montantTtc);
  292.             }
  293.             $factureFinanceMantant->setTva($montantTva);
  294.             $this->em->persist($factureFinanceMantant);
  295.             $this->em->flush();
  296.         }
  297.         $nbrDivision = 100;
  298.         $facture->setInvoiceAccountingCurrency($data['total']['accountingCurrency']);
  299.         $facture->setMonatantHt($data['total']['amount']/$nbrDivision);
  300.         $facture->setInvoiceTtcNetPayable($data['total']['netPayable']/$nbrDivision);
  301.         $facture->setMonatantHtNetAmount($data['total']['netAmount']/$nbrDivision);
  302.         $facture->setInvoiceReductionAmount($data['total']['reductionAmount']/$nbrDivision);
  303.         $facture->setInvoiceCostAmount($data['total']['costAmount']/$nbrDivision);
  304.         $facture->setInvoiceTtcAmountIncludingTax($data['total']['amountIncludingTax']/$nbrDivision);
  305.         $facture->setTva($data['total']['vatAmount']/$nbrDivision);
  306.         $facture->setMonatantTtc(($data['total']['amount']/$nbrDivision) + ($data['total']['vatAmount']/$nbrDivision));
  307.         $this->em->persist($facture);
  308.         $this->em->flush();
  309.     }
  310.     public function addAvoir($data){
  311.         $avoir = new Avoir();
  312.         $avoir->setIsRfe(true);
  313.         $avoir->setNumeroAvoir($data['invoice_number_fournisseur']);
  314.         $avoir->setFournisseur($data['fournisseur']);
  315.         $avoir->setSpv($data['spv']);
  316.         $avoir->setDateAvoir(new \DateTime($data['invoice_issue_date']));
  317. //        $doc = $this->importPdf($data['invoice_link']);
  318. //        if($doc){
  319. //            $avoir->setFileAvoir($doc);
  320. //        }
  321.         $avoir->setUrlFacture($data['invoice_link']);
  322.         $avoir->setStatus(Avoir::STATUS_A_COMPLETER);
  323.         $avoir->setInvoiceDocumentType($data['invoice_document_type']);
  324.         $avoir->setTauxTva(0);
  325.         $avoir->setInvoiceCurrency($data['currency']);
  326.         $avoir->setInvoiceInternational($data['invoice_international']);
  327.         $avoir->setInvoiceStatus($data['invoice_status']);
  328.         $avoir->setInvoiceNumberEfac($data['invoice_number_efac']);
  329.         $avoir->setInvoicePaId($data['invoice_pa_id']);
  330.         $this->em->persist($avoir);
  331.         $this->em->flush();
  332.         foreach ($data['line'] as $line){
  333.             $nbrDivision = 100;
  334.             $avoirMantant = new AvoirMontantTva();
  335.             $avoirMantant->setAvoir($avoir);
  336.             $avoirMantant->setUnitPrice($line['unitPrice']/$nbrDivision);
  337.             $avoirMantant->setNumber($line['number']);
  338.             $avoirMantant->setNote($line['note']);
  339.             $avoirMantant->setUnit($line['unit']);
  340.             $avoirMantant->setMontantHt($line['amount']/$nbrDivision);
  341.             $avoirMantant->setQuantity($line['quantity']);
  342.             $avoirMantant->setVatType($line['vatType']);
  343.             $avoirMantant->setTauxTva($line['vatRate']);
  344.             $montantTva = (($line['amount']/$nbrDivision) * $line['vatRate']) / 100 ;
  345.             $montantTtc = $montantTva + ($line['amount']/$nbrDivision);
  346.             if(in_array($line['vatType'],["E","AE","K","G","O","Z"])){
  347.                 $avoirMantant->setMontantTtc($line['amount']/$nbrDivision);
  348.             }else{
  349.                 $montantTtc = $montantTva + ($line['amount']/$nbrDivision);
  350.                 $avoirMantant->setMontantTtc($montantTtc);
  351.             }
  352.             $avoirMantant->setTva($montantTva);
  353.             $this->em->persist($avoirMantant);
  354.             $this->em->flush();
  355.         }
  356.         $nbrDivision = 100;
  357.         $avoir->setInvoiceAccountingCurrency($data['total']['accountingCurrency']);
  358.         $avoir->setMonatantHt($data['total']['amount']/$nbrDivision);
  359.         $avoir->setInvoiceTtcNetPayable($data['total']['netPayable']/$nbrDivision);
  360.         $avoir->setMonatantHtNetAmount($data['total']['netAmount']/$nbrDivision);
  361.         $avoir->setInvoiceReductionAmount($data['total']['reductionAmount']/$nbrDivision);
  362.         $avoir->setInvoiceCostAmount($data['total']['costAmount']/$nbrDivision);
  363.         $avoir->setInvoiceTtcAmountIncludingTax($data['total']['amountIncludingTax']/$nbrDivision);
  364.         $avoir->setTva($data['total']['vatAmount']/$nbrDivision);
  365.         $avoir->setMonatantTtc(($data['total']['amount']/$nbrDivision) + ($data['total']['vatAmount']/$nbrDivision));
  366.         $this->em->persist($avoir);
  367.         $this->em->flush();
  368.     }
  369.     public function addFactureV2($data){
  370.         $typeDoc = $this->getTypeDocument($data['invoice_document_type']);
  371.         if($typeDoc == EfacData::type_acompte){
  372.             $type = 'Acompte';
  373.         }else{
  374.             $type = 'Facture';
  375.         }
  376.         $facture = new FactureFinance();
  377.         $facture->setIsRfe(false);
  378.         $facture->setIsRfe2(true);
  379.         $facture->setNumeroFacture($data['invoice_number_fournisseur']);
  380.         $facture->setCategory($type);
  381.         $facture->setFournisseur($data['fournisseur']);
  382.         $facture->setSpv($data['spv']);
  383.         $facture->setDateFacture(new \DateTime($data['invoice_issue_date']));
  384.         $facture->setDelaiPaiementDate(new \DateTime($data['invoice_due_date']));
  385.         $facture->setDelaiPaiement((new \DateTime($data['invoice_due_date']))->diff(new \DateTime($data['invoice_issue_date']))->days);
  386.         $facture->setUrlFacture($data['invoice_link']);
  387.         if( $data['invoice_status'] == 'Rejeté'){
  388.             $facture->setStatus(FactureFinance::STATUS_REFUS);
  389.         }else{
  390.             $facture->setStatus(FactureFinance::STATUS_A_COMPLETER);
  391.         }
  392.         $facture->setInvoiceDocumentType($data['invoice_document_type']);
  393.         $facture->setInvoiceInternational($data['invoice_international']);
  394.         $facture->setInvoiceStatus($data['invoice_status']);
  395.         $facture->setInvoiceNumberEfac($data['invoice_number_efac']);
  396.         $facture->setInvoicePaId($data['invoice_pa_id']);
  397.         // Montants bruts (pas de division par 100 en V2)
  398.         $facture->setMonatantHt($data['invoice_amount_ht']);
  399.         $facture->setTauxTva($data['invoice_vat_rate']);
  400.         $facture->setTva($data['invoice_amount_vat']);
  401.         $facture->setMonatantTtc($data['invoice_amount_ttc']);
  402.         // Nouveaux attributs V2
  403.         $facture->setInvoiceCodeRef1($data['invoice_codeREF1']);
  404.         $facture->setInvoiceRefProjet($data['invoice_ref_projet']);
  405.         $facture->setInvoiceValideurN1($data['invoice_valideur_N1']);
  406.         $facture->setInvoiceValideurN2($data['invoice_valideur_N2']);
  407.         $facture->setInvoiceValideurN3($data['invoice_valideur_N3']);
  408.         $facture->setInvoiceDateValidationN1($this->parseDate($data['invoice_date_validation_N1']));
  409.         $facture->setInvoiceDateValidationN2($this->parseDate($data['invoice_date_validation_N2']));
  410.         $facture->setInvoiceDateValidationN3($this->parseDate($data['invoice_date_validation_N3']));
  411.         // Lien vers le projet (invoice_ref_projet = codeProject)
  412.         if(!empty($data['project'])){
  413.             $projectFactureFinance = new ProjectFactureFinance();
  414.             $projectFactureFinance->setProject($data['project']);
  415.             $projectFactureFinance->setFactureFinance($facture);
  416.             $facture->addProjectFactureFinance($projectFactureFinance);
  417.             $this->em->persist($projectFactureFinance);
  418.         }
  419.         $this->em->persist($facture);
  420.         $this->em->flush();
  421.         $this->notification->setCompteurErpiPiece($facture);
  422.         $this->notification->setCompteurErpiEcriture($facture);
  423.     }
  424.     public function addAvoirV2($data){
  425.         $avoir = new Avoir();
  426.         $avoir->setIsRfe(false);
  427.         $avoir->setIsRfe2(true);
  428.         $avoir->setNumeroAvoir($data['invoice_number_fournisseur']);
  429.         $avoir->setFournisseur($data['fournisseur']);
  430.         $avoir->setSpv($data['spv']);
  431.         $avoir->setDateAvoir(new \DateTime($data['invoice_issue_date']));
  432.         $avoir->setUrlFacture($data['invoice_link']);
  433.         if( $data['invoice_status'] == 'Rejeté'){
  434.             $avoir->setStatus(Avoir::STATUS_REFUS);
  435.         }else{
  436.             $avoir->setStatus(Avoir::STATUS_A_COMPLETER);
  437.         }
  438.         $avoir->setInvoiceDocumentType($data['invoice_document_type']);
  439.         $avoir->setInvoiceInternational($data['invoice_international']);
  440.         $avoir->setInvoiceStatus($data['invoice_status']);
  441.         $avoir->setInvoiceNumberEfac($data['invoice_number_efac']);
  442.         $avoir->setInvoicePaId($data['invoice_pa_id']);
  443.         // Montants bruts (pas de division par 100 en V2)
  444.         $avoir->setMonatantHt($data['invoice_amount_ht']);
  445.         $avoir->setTauxTva($data['invoice_vat_rate']);
  446.         $avoir->setTva($data['invoice_amount_vat']);
  447.         $avoir->setMonatantTtc($data['invoice_amount_ttc']);
  448.         // Nouveaux attributs V2
  449.         $avoir->setInvoiceCodeRef1($data['invoice_codeREF1']);
  450.         $avoir->setInvoiceRefProjet($data['invoice_ref_projet']);
  451.         $avoir->setInvoiceValideurN1($data['invoice_valideur_N1']);
  452.         $avoir->setInvoiceValideurN2($data['invoice_valideur_N2']);
  453.         $avoir->setInvoiceValideurN3($data['invoice_valideur_N3']);
  454.         $avoir->setInvoiceDateValidationN1($this->parseDate($data['invoice_date_validation_N1']));
  455.         $avoir->setInvoiceDateValidationN2($this->parseDate($data['invoice_date_validation_N2']));
  456.         $avoir->setInvoiceDateValidationN3($this->parseDate($data['invoice_date_validation_N3']));
  457.         // Lien vers le projet (invoice_ref_projet = codeProject)
  458.         if(!empty($data['project'])){
  459.             $projectAvoir = new ProjectAvoir();
  460.             $projectAvoir->setProject($data['project']);
  461.             $projectAvoir->setAvoir($avoir);
  462.             $avoir->addProjectAvoir($projectAvoir);
  463.             $this->em->persist($projectAvoir);
  464.         }
  465.         $this->em->persist($avoir);
  466.         $this->em->flush();
  467.         $this->notification->setCompteurErpiPiece(null,$avoir);
  468.         $this->notification->setCompteurErpiEcriture(null,$avoir);
  469.     }
  470.     private function parseDate($value)
  471.     {
  472.         if (empty($value)) {
  473.             return null;
  474.         }
  475.         return new \DateTime($value);
  476.     }
  477.     public function importPdf($url)
  478.     {
  479.         $client = HttpClient::create();
  480.         $response = $client->request('GET', $url);
  481.         if ($response->getStatusCode() !== 200) {
  482.             return null;
  483.         }
  484.         $content = $response->getContent();
  485.         $name = md5(uniqid());
  486.         $contentType = $response->getHeaders()['content-type'][0];
  487.         $extension = explode('/', $contentType)[1];
  488.         file_put_contents(
  489.             $this->params->get('kernel.project_dir') . '/public/uploads/'.$name.'.'.$extension,
  490.             $content
  491.         );
  492.         $doc = new DocUpload();
  493.         $doc->setName('document');
  494.         $doc->setPath($name.'.'.$extension);
  495.         $this->em->persist($doc);
  496.         $this->em->flush();
  497.         return $doc;
  498.     }
  499.     public function addFactureOrAvoirV2($request){
  500.         $data = json_decode($request->getContent(), true);
  501.         if (!$data) {
  502.             $this->addEfacDataLog('',$request->getContent(),'JSON invalide');
  503.             return ['error' => 'JSON invalide' , 'status'=> Response::HTTP_BAD_REQUEST];
  504.         }
  505.         //check field blanc date number choice
  506.         $validator = Validation::createValidator();
  507.         $constraint = new Assert\Collection([
  508.             'documentList' => [
  509.                 new Assert\NotBlank(),
  510.                 new Assert\Type('array'),
  511.                 new Assert\Count(['min' => 1]),
  512.                 new Assert\All([
  513.                     new Assert\Collection([
  514.                         'invoice_document_type' => [new Assert\NotBlank()],
  515.                         'invoice_international' => [new Assert\NotBlank(), new Assert\Choice(['0', '1'])],
  516.                         'invoice_status' => [new Assert\NotBlank(), new Assert\Choice(['Accepté', 'Rejeté'])],
  517.                         'invoice_number_efac' => [new Assert\NotBlank()],
  518.                         'invoice_number_fournisseur' => [new Assert\NotBlank()],
  519.                         'invoice_issue_date' => [new Assert\Date()],
  520.                         'invoice_due_date' => [new Assert\NotBlank(), new Assert\Date()],
  521.                         'invoice_supplier' => [new Assert\NotBlank()],
  522.                         'invoice_codeREF1' => [new Assert\NotBlank()],
  523.                         'invoice_spv' => [new Assert\NotBlank()],
  524.                         'invoice_amount_ht' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  525.                         'invoice_vat_rate' => [new Assert\Optional([new Assert\Type('numeric')])],
  526.                         'invoice_amount_vat' => [new Assert\Optional([new Assert\Type('numeric')])],
  527.                         'invoice_amount_ttc' => [new Assert\NotBlank(), new Assert\Type('numeric')],
  528.                         'invoice_valideur_N1' => [],
  529.                         'invoice_valideur_N2' => [],
  530.                         'invoice_valideur_N3' => [],
  531.                         'invoice_date_validation_N1' => [ new Assert\Date()],
  532.                         'invoice_date_validation_N2' => [ new Assert\Date()],
  533.                         'invoice_date_validation_N3' => [ new Assert\Date()],
  534.                         'invoice_link' => [new Assert\NotBlank()],
  535.                         'invoice_pa_id' => [],
  536.                         'invoice_ref_projet' => [],
  537.                     ])
  538.                 ])
  539.             ],
  540.             'count' => [new Assert\NotBlank(), new Assert\Type('integer')],
  541.             'transactionId' => [new Assert\NotBlank()]
  542.         ]);
  543.         $violations = $validator->validate($data, $constraint);
  544.         if (count($violations) > 0) {
  545.             $errors = [];
  546.             foreach ($violations as $violation) {
  547.                 $errors[] = [
  548.                     'field' => $violation->getPropertyPath(),
  549.                     'message' => $violation->getMessage()
  550.                 ];
  551.             }
  552.             $this->addEfacDataLog($data['transactionId'],$request->getContent(),json_encode($errors));
  553.             return ['errors' => $errors , 'status'=> Response::HTTP_BAD_REQUEST];
  554.         }else{
  555.             $errors = [];
  556.             //check field data base de donnée
  557.             foreach ($data['documentList'] as $key=>&$datum){
  558.                 $typeDoc = $this->getTypeDocument($datum['invoice_document_type']);
  559.                 $numero = $datum['invoice_number_efac'];
  560.                 $codeFournisseur = $datum['invoice_supplier'];
  561.                 $codeSpv = $datum['invoice_spv'];
  562.                 if($typeDoc == EfacData::type_facture || $typeDoc == EfacData::type_acompte){
  563.                     $facture = $this->em->getRepository(FactureFinance::class)->findOneBy(['invoiceNumberEfac'=>$numero]);
  564.                     if($facture){
  565.                         $errors[] = [
  566.                             'field' => "[documentList][$key][invoice_number_efac]",
  567.                             'message' => "Ce numéro de facture existe déjà."
  568.                         ];
  569.                     }
  570.                 }elseif($typeDoc == EfacData::type_avoir){
  571.                     $avoir = $this->em->getRepository(Avoir::class)->findOneBy(['invoiceNumberEfac'=>$numero]);
  572.                     if($avoir){
  573.                         $errors[] = [
  574.                             'field' => "[documentList][$key][invoice_number_efac]",
  575.                             'message' => "Ce numéro d’avoir existe déjà."
  576.                         ];
  577.                     }
  578.                 }
  579.                 $spv = $this->em->getRepository(Spv::class)->findOneBy(['raisonSociale'=>$codeSpv]);
  580.                 $fournisseur = $this->em->getRepository(Fournisseur::class)->findNotArchiveByCodeSingle($codeFournisseur);
  581.                 $project = $this->em->getRepository(Project::class)->findOneBy(['codeProject'=>$datum['invoice_ref_projet']]);
  582.                 if(!$spv){
  583.                     $errors[] = [
  584.                         'field' => "[documentList][$key][invoice_spv]",
  585.                         'message' => "Le siren ne correspond à aucune SPV."
  586.                     ];
  587.                 }
  588.                 if(!$fournisseur){
  589.                     $errors[] = [
  590.                         'field' => "[documentList][$key][invoice_supplier]",
  591.                         'message' => "Le code ne correspond à aucun fournisseur."
  592.                     ];
  593.                 }
  594.                 // Projet introuvable = non bloquant : la facture/avoir est créée sans lien projet.
  595.                 $datum['spv'] = $spv;
  596.                 $datum['fournisseur'] = $fournisseur;
  597.                 $datum['project'] = $project;
  598. //                $client = HttpClient::create();
  599. //                $response = $client->request('GET', $datum['invoice_link']);
  600. //                if ($response->getStatusCode() !== 200) {
  601. //                    $errors[] = [
  602. //                        'field' => "[documentList][$key][invoice_link]",
  603. //                        'message' => "URL de fichier erronée"
  604. //                    ];
  605. //                }
  606.             }
  607.             if (count($errors) > 0) {
  608.                 $this->addEfacDataLog($data['transactionId'],$request->getContent(),json_encode($errors));
  609.                 return ['errors' => $errors , 'status'=> Response::HTTP_CONFLICT];
  610.             }else{
  611.                 foreach ($data['documentList'] as $key=>$datum){
  612.                     $typeDoc = $this->getTypeDocument($datum['invoice_document_type']);
  613.                     if($typeDoc == EfacData::type_facture || $typeDoc == EfacData::type_acompte){
  614.                         $this->addFactureV2($datum);
  615.                     }elseif($typeDoc == EfacData::type_avoir){
  616.                         $this->addAvoirV2($datum);
  617.                     }else{
  618.                         $errors[] = [
  619.                             'field' => "[documentList][$key][invoice_document_type]",
  620.                             'message' => "Le type de document ne correspond ni à une facture ni à un avoir."
  621.                         ];
  622.                         $this->addEfacDataLog($data['transactionId'],$request->getContent(),json_encode($errors));
  623.                         return ['errors' => $errors , 'status'=> Response::HTTP_CONFLICT];
  624.                     }
  625.                 }
  626.                 $this->addEfacDataLog($data['transactionId'],$request->getContent(),Response::HTTP_OK);
  627.                 return ['message' => 'Facture reçue et enregistrée' , 'status'=> Response::HTTP_OK];
  628.             }
  629.         }
  630.         return ['errors' => 'Requête invalide' , 'status'=> Response::HTTP_BAD_REQUEST];
  631.     }
  632. }