%%%
% Facture
%%%
\def\filedateFacture{2026/05/28}%
\def\fileversionFacture{0.1a}%
\message{-- \filedateFacture\space v\fileversionFacture}%
%
\newcounter{PfCChoixFrais}%

\makeatletter

\setKVdefault[Facture]{Largeur=222pt,Enseigne={},DateFacture={},HeureAchat={},Total,SousTotal,SousTotalFrais,UK=false,US=false,CFA=false,CFP=false,CHF=false,Euro=false,Solution=false,Couleur={},Service={},Frais={},Unitaire,TexteQTE=Quantité,TextePrixUnitaire=Prix unitaire}%

\NewDocumentCommand\PfC@PrixInsulteFacture{sm}{%
  \ifboolKV[Facture]{Solution}{%
    \textcolor{PfCTicketCouleurSolution}{\IfBooleanTF{#1}{\num{#2}}{#2}}%
  }{%
    \stepcounter{PfCNbInsulte}%
    \PointsSuspension{12345}%
  }%
}%

\NewDocumentCommand\Facture{som}{%
  \setcounter{PfCNbInsulte}{0}%
  \setcounter{PfCChoixService}{0}%
  \setcounter{PfCChoixFrais}{0}%
  \useKVdefault[Facture]%
  \setKV[Facture]{#2}%
  \ifemptyKV[Facture]{Couleur}{}{\colorlet{PfCTicketCouleurSolution}{\useKV[Facture]{Couleur}}\setKV[Facture]{Solution}}%
  \setlength{\PfCTicketLarg}{\useKV[Facture]{Largeur}}%
  \setsepchar[*]{,*/}\reademptyitems%
  \readlist*\PfC@ListeAchats{#3}%
  % On fait six listes pour les retenir
  % Liste Quantités
  \edef\PfC@FooQuantites{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \StrChar{\PfC@ListeAchats[\compteurcnt,1]}{1}[\MyLetter]%
    \IfStrEq{\MyLetter}{!}{%
      \StrBehind{\PfC@ListeAchats[\compteurcnt,1]}{!}[\Titi]%
      \edef\PfC@FooQuantites{\PfC@FooQuantites \Titi,}%
    }{%
      \edef\PfC@FooQuantites{\PfC@FooQuantites \PfC@ListeAchats[\compteurcnt,1],}%
    }%
  }%
  % Liste NatureQuantités
  \edef\PfC@FooNatureQuantites{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \edef\PfC@FooNatureQuantites{\PfC@FooNatureQuantites \PfC@ListeAchats[\compteurcnt,2],}%
  }%
  % Liste Elements
  \edef\PfC@FooElements{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \edef\PfC@FooElements{\PfC@FooElements \PfC@ListeAchats[\compteurcnt,3],}%
  }%
  % Liste Prix Unitaire
  \edef\PfC@FooPUnitaires{}%
  \edef\PfC@FooMultiplicateurs{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \StrCount{\PfC@ListeAchats[\compteurcnt,4]}{:}[\PfC@NbTwoCount]%
    \edef\PfC@MultiplicateurRetenu{1}%
    \ifnum\PfC@NbTwoCount>0\relax%
      \StrBefore{\PfC@ListeAchats[\compteurcnt,4]}{:}[\PfC@EcritureRetenue]%
      \StrBehind{\PfC@ListeAchats[\compteurcnt,4]}{:}[\PfC@MultiplicateurRetenu]%
    \else%
      \edef\PfC@EcritureRetenue{\PfC@ListeAchats[\compteurcnt,4]}%
    \fi%
    \edef\PfC@FooMultiplicateurs{\PfC@FooMultiplicateurs \PfC@MultiplicateurRetenu,}%
    \StrChar{\PfC@EcritureRetenue}{1}[\MyLetter]%
    \IfStrEqCase{\MyLetter}{%
      {!}{%
        \StrBehind{\PfC@EcritureRetenue}{!}[\Titi]%
        \StrChar{\Titi}{1}[\Toto]%
        \IfStrEq{\Toto}{*}{%
          \StrBehind{\PfC@EcritureRetenue}{!*}[\Tata]%
          \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires \Tata,}%
        }{%
          \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires \Titi,}%
        }%
      }% 
      {*}{\StrBehind{\PfC@EcritureRetenue}{*}[\Titi]%
        \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires \Titi,}}%
    }[\edef\PfC@FooPUnitaires{\PfC@FooPUnitaires \PfC@EcritureRetenue,}]%
  }%
  % Liste UniteQuantites
  \edef\PfC@FooUniteQuantites{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \edef\PfC@FooUniteQuantites{\PfC@FooUniteQuantites \PfC@ListeAchats[\compteurcnt,5],}%
  }%
  % On les lit
  \setsepchar{,}\reademptyitems%
  \readlist*\PfC@ListeQuantites{\PfC@FooQuantites}%
  \readlist*\PfC@ListeNatureQuantites{\PfC@FooNatureQuantites}%
  \readlist*\PfC@ListeElements{\PfC@FooElements}%
  \readlist*\PfC@ListePUnitaires{\PfC@FooPUnitaires}%
  \readlist*\PfC@ListeUniteQuantites{\PfC@FooUniteQuantites}%
  \readlist*\PfC@ListeMultiplicateursRetenus{\PfC@FooMultiplicateurs}%
  \reademptyitems%
  % On calcul le coût total
  \edef\PfC@TCTotal{0}%
  \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeAchatslen}}\do{%
    \edef\PfC@TCTotal{\fpeval{\PfC@TCTotal+\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}%
  }%
  \ifemptyKV[Facture]{Service}{}{%
    % On décompose la clé
    \StrChar{\useKV[Facture]{Service}}{1}[\MyLetter]%
    % Si le premier caractère est !, on regarde si le deuxième caractère est une étoile
    \IfStrEq{\MyLetter}{!}{%
      \StrChar{\useKV[Facture]{Service}}{2}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[Facture]{Service}}{2}[\PfC@TCValeurService]%
        \setcounter{PfCChoixService}{3}%
      }{%
        \StrGobbleLeft{\useKV[Facture]{Service}}{1}[\PfC@TCValeurService]%
        \setcounter{PfCChoixService}{1}%
      }%
    }{%il faut regarder si c'est une étoile
      \StrChar{\useKV[Facture]{Service}}{1}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[Facture]{Service}}{1}[\PfC@TCValeurService]%
        \setcounter{PfCChoixService}{2}%
      }{%
        \edef\PfC@TCValeurService{\useKV[Facture]{Service}}%
        \setcounter{PfCChoixService}{0}%
      }%
    }%
    % On fait les calculs associés à la clé.
    \edef\PfC@TCSousTotal{\PfC@TCTotal}%
    \edef\PfC@TCService{\fpeval{\PfC@TCValeurService*\PfC@TCSousTotal/100}}%
    \edef\PfC@TCTotal{\fpeval{\PfC@TCSousTotal+\PfC@TCService}}%
  }%
  \ifemptyKV[Facture]{Frais}{}{%
    % On décompose la clé
    \StrChar{\useKV[Facture]{Frais}}{1}[\MyLetter]%
    % Si le premier caractère est !, on regarde si le deuxième caractère est une étoile
    \IfStrEq{\MyLetter}{!}{%
      \StrChar{\useKV[Facture]{Frais}}{2}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[Facture]{Frais}}{2}[\PfC@TCValeurFrais]%
        \setcounter{PfCChoixFrais}{3}%
      }{%
        \StrGobbleLeft{\useKV[Facture]{Frais}}{1}[\PfC@TCValeurFrais]%
        \setcounter{PfCChoixFrais}{1}%
      }%
    }{%il faut regarder si c'est une étoile
      \StrChar{\useKV[Facture]{Frais}}{1}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[Facture]{Frais}}{1}[\PfC@TCValeurFrais]%
        \setcounter{PfCChoixFrais}{2}%
      }{%
        \edef\PfC@TCValeurFrais{\useKV[Facture]{Frais}}%
        \setcounter{PfCChoixFrais}{0}%
      }%
    }%
    % On fait les calculs associés à la clé.
    \edef\PfC@TCSousTotalFrais{\PfC@TCTotal}%
    \edef\PfC@TCFrais{\PfC@TCValeurFrais}%
    \edef\PfC@TCTotal{\fpeval{\PfC@TCSousTotalFrais+\PfC@TCFrais}}%
  }%
  \IfBooleanTF{#1}{%
    \ttfamily
    \begin{tabular}{|m{0.48\PfCTicketLarg}|m{0.48\PfCTicketLarg}|m{0.48\PfCTicketLarg}|m{0.25\PfCTicketLarg}|}%
      \ifemptyKV[Facture]{Enseigne}{}{%
      \hhline{----}
      \uppercase{&}\uppercase{&}\uppercase{&}\\%
      \multicolumn{4}{|c|}{\Large\bfseries\useKV[Facture]{Enseigne}}\\%
      \uppercase{&}\uppercase{&}\uppercase{&}\\%
      }%
      \hhline{----}%
      \rowcolor{LightSteelBlue}\footnotesize\sc Description&\centering \footnotesize\sc \useKV[Facture]{TexteQTE}.&\centering\footnotesize\sc \useKV[Facture]{TextePrixUnitaire}&\hfill\footnotesize\sc Prix \ifemptyKV[Facture]{Service}{Net}{H.T.}\\%
      \hhline{----}
      \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeAchatslen}}\do{%
      \PfC@ListeElements[##1]&%
                               \centering
                               \footnotesize%
                               \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
                               \IfStrEq{\MyLetter}{!}{%
                               \PfC@PrixInsulteFacture*{\PfC@ListeQuantites[##1]}}{\xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[Facture]{Unitaire}{\num{1}}{}}{\num{\PfC@ListeQuantites[##1]}}}~\PfC@ListeNatureQuantites[##1]%
                              &%Prix unitaire
                                \hfill%
                                \footnotesize%
                                % Savoir si le nombre d'articles est affiché
                                \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
                                % Si le nombre d'articles n'est pas affiché, il faut impérativement afficher le prix unitaire
                                \IfStrEq{\MyLetter}{!}{%
                                \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
                                }{%
                                  % On regarde si on affiche le prix unitaire
                                \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLettera]%
                                % Si c'est un !, on affiche pas
                                % Sinon, on affiche
                                \IfStrEq{\MyLettera}{!}{%
                                \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}%
                                }{%
                                \xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[Facture]{Unitaire}{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}{}}{%
                                \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
                                }%
                                }%
                                }%
                                ~\PfC@ListeUniteQuantites[##1]%
                                           &\hfill%ok
                                             \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLetter]%
                                             % Si le premier caractère est !, il faut regarder si le deuxième caractère est une étoile
                                             \IfStrEq{\MyLetter}{!}{%
                                             \StrChar{\PfC@ListeAchats[##1,4]}{2}[\MyLettera]%
                                             \IfStrEq{\MyLettera}{*}{%
                                             \PfC@PrixInsulteFacture{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}}%
                                             }{%
                                             \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}%
                                             }%
                                             }{%il faut regarder si c'est une étoile
                                             \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLettera]%
                                             \IfStrEq{\MyLettera}{*}{%
                                             \PfC@PrixInsulteFacture{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}}%
                                             }{%
                                             \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}%
                                             }%
                                             }%
      \\
      \hhline{----}
      }%
      % Partie Service
      \ifemptyKV[Facture]{Service}{}{%
      \multicolumn{2}{c|}{}\uppercase{&}\cellcolor{Cornsilk}Total H.T.\uppercase{&}\cellcolor{Cornsilk}\hfill\ifboolKV[Facture]{SousTotal}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotal}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCSousTotal}}\fi}{\PfC@PrixTicket{\PfC@TCSousTotal}}%
      \\%
      \hhline{~~--}
      \multicolumn{2}{c|}{}&\cellcolor{Cornsilk}T.V.A.~%
                             \ifodd\thePfCChoixService\relax\PfC@PrixInsulteFacture{\num{\PfC@TCValeurService}}\else\num{\PfC@TCValeurService}\fi~\si{\percent}%
                              &\cellcolor{Cornsilk}\hfill%
                                \ifnum\thePfCChoixService>1\relax \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCService}}\else\PfC@PrixTicket{\PfC@TCService}\fi%
      \\
      }%
      % Partie Frais
      \ifemptyKV[Facture]{Frais}{}{%
      \hhline{~~--}
      \multicolumn{2}{c|}{}&\cellcolor{Cornsilk}Sous-Total\uppercase{&}\cellcolor{Cornsilk}\hfill\ifboolKV[Facture]{SousTotalFrais}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotalFrais}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCSousTotalFrais}}\fi}{\PfC@PrixTicket{\PfC@TCSousTotalFrais}}\\%
      \hhline{~~--}
      \multicolumn{2}{c|}{}&\cellcolor{Cornsilk}Frais %
                              &\cellcolor{Cornsilk}\hfill\ifodd\thePfCChoixFrais\relax \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCValeurFrais}}\else\PfC@PrixTicket{\PfC@TCValeurFrais}\fi%
      \\
      }%
      % Fin  
      \hhline{~~--}
      \multicolumn{2}{c|}{}&\cellcolor{Cornsilk}Total\ifemptyKV[Facture]{Service}{}{ T.T.C.}&\cellcolor{Cornsilk}\hfill\ifboolKV[Facture]{Total}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCTotal}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCTotal}}\fi}{\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCTotal}}}\\%
      \hhline{~~--}
      \ifemptyKV[Facture]{DateFacture}{}{%
      \multicolumn{4}{|c|}{\footnotesize\useKV[Facture]{DateFacture}\qquad\useKV[Facture]{HeureAchat}}\\%
      \hhline{----}
      }%
    \end{tabular}
  }{%
    {\ttfamily%
      \begin{NiceTabular}{m{0.48\PfCTicketLarg}m{0.48\PfCTicketLarg}m{0.48\PfCTicketLarg}m{0.225\PfCTicketLarg}}%
        \ifemptyKV[Facture]{Enseigne}{}{%
          &&&\\%
          \Block[draw,borders={l,r}]{1-4}{\Large\bfseries\useKV[Facture]{Enseigne}}&&&\\%
          \\%
          \Cdots\\%
          \\%
        }%
        \rowcolor{LightSteelBlue}\Block[draw,l]{}{\footnotesize\sc Description}&\Block[draw]{}{\footnotesize\sc \useKV[Facture]{TexteQTE}}&\Block[draw]{}{\footnotesize\sc \useKV[Facture]{TextePrixUnitaire}}&\Block[draw,r]{}{\footnotesize\sc Prix \ifemptyKV[Facture]{Service}{Net}{H.T.}}\\%
        \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeAchatslen}}\do{%
          \Block[draw,l]{}{\PfC@ListeElements[##1]}&%
          \Block[draw]{}{%
            \footnotesize%
            \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
            \IfStrEq{\MyLetter}{!}{\PfC@PrixInsulteFacture*{\PfC@ListeQuantites[##1]}}{\xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[Facture]{Unitaire}{\num{1}}{}}{\num{\PfC@ListeQuantites[##1]}}}~\PfC@ListeNatureQuantites[##1]%
          }&%
          \Block[draw,r]{}{%
            \footnotesize
            % Savoir si le nombre d'articles est affiché
            \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
            % Si le nombre d'articles n'est pas affiché, il faut impérativement afficher le prix unitaire
            \IfStrEq{\MyLetter}{!}{%
              \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
            }{%
              % On regarde si on affiche le prix unitaire
              \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLettera]%
              % Si c'est un !, on affiche pas
              % Sinon, on affiche
              \IfStrEq{\MyLettera}{!}{%
                \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}%
              }{%
                \xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[Facture]{Unitaire}{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}{}}{%
                    \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
                  }%
                }%
              }%
              ~\PfC@ListeUniteQuantites[##1]%
          }%
          &\Block[draw,r]{}{%
            \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLetter]%
            % Si le premier caractère est !, il faut regarder si le deuxième caractère est une étoile
            \IfStrEq{\MyLetter}{!}{%
              \StrChar{\PfC@ListeAchats[##1,4]}{2}[\MyLettera]%
              \IfStrEq{\MyLettera}{*}{%
                \PfC@PrixInsulteFacture{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}}%
              }{%
                \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}%
              }%
            }{%il faut regarder si c'est une étoile
              \StrChar{\PfC@ListeAchats[##1,4]}{1}[\MyLettera]%
              \IfStrEq{\MyLettera}{*}{%
                \PfC@PrixInsulteFacture{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}}%
              }{%
                \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]/\PfC@ListeMultiplicateursRetenus[##1]}}%
              }%
            }%
          }\\
        }%
        % Partie Service
        \ifemptyKV[Facture]{Service}{}{%
          \Block{1-2}{}&&\Block[draw,fill=Cornsilk,l]{}{Total H.T.}&\Block[draw,fill=Cornsilk,r]{}{\ifboolKV[Facture]{SousTotal}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotal}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCSousTotal}}\fi}{\PfC@PrixTicket{\PfC@TCSousTotal}}%
          }\\%
          \Block{1-2}{}&&\Block[draw,fill=Cornsilk,l]{}{T.V.A. %
            \ifodd\thePfCChoixService\relax \PfC@PrixInsulteFacture{\num{\PfC@TCValeurService}}\else\num{\PfC@TCValeurService}\fi~\si{\percent}}%
          &\Block[draw,fill=Cornsilk,r]{}{%
            \ifnum\thePfCChoixService>1\relax \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCService}}\else\PfC@PrixTicket{\PfC@TCService}\fi%
          }\\
        }%
        % Partie Frais
        \ifemptyKV[Facture]{Frais}{}{%
          \Block{1-2}{}&&\Block[draw,fill=Cornsilk,l]{}{Sous-Total}&\Block[draw,fill=Cornsilk,r]{}{\ifboolKV[Facture]{SousTotalFrais}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotalFrais}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCSousTotalFrais}}\fi}{\PfC@PrixTicket{\PfC@TCSousTotalFrais}}}\\%
          \Block{1-2}{}&&\Block[draw,fill=Cornsilk,l]{}{Frais}%
          &\Block[draw,fill=Cornsilk,r]{}{\ifodd\thePfCChoixFrais\relax \PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCValeurFrais}}\else\PfC@PrixTicket{\PfC@TCValeurFrais}\fi%
          }\\%
        }%
        \Block{1-2}{}&&\Block[draw,fill=Cornsilk,l]{}{Total\ifemptyKV[Facture]{Service}{}{ T.T.C.}}&\Block[draw,fill=Cornsilk,r]{}{\ifboolKV[Facture]{Total}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCTotal}\else\PfC@PrixInsulteFacture{\PfC@PrixTicket{\PfC@TCTotal}}\fi}{\PfC@PrixTicket{\PfC@TCTotal}}}\\%
        \ifemptyKV[Facture]{DateFacture}{}{\Block{1-4}{\footnotesize\useKV[Facture]{DateFacture}\qquad\useKV[Facture]{HeureAchat}}&&&\\%
        }%
      \end{NiceTabular}
    }%
  }%
}%
\makeatother