%%%
% Ticket de caisse
%%%
\def\filedateTicketCaisse{2025/11/23}%
\def\fileversionTicketCaisse{0.1b}%
\message{-- \filedateTicketCaisse\space v\fileversionTicketCaisse}%
%
\newcounter{PfCNbInsulte}%
\newcounter{PfCChoixService}%
\setcounter{PfCNbInsulte}{0}%
\setcounter{PfCChoixService}{0}%
%
\newlength\PfCTicketLarg

%https://tex.stackexchange.com/questions/356103/chalkboard-background-to-write-on?noredirect=1&lq=1
\newtcolorbox{ardoise}[1][]{%
  enhanced,
  nobeforeafter,
  left=1mm,right=1mm,
  colback={green!20!black},
  colupper=white,
  fontupper=\large,
  notitle,
  sharp corners,
  colframe=brown!70!black,
  boxrule=0.5mm,
  drop fuzzy shadow,
  #1
}

\makeatletter

\NewDocumentCommand\PfC@PrixInsulte{sm}{%
  \setsepchar{,}\ignoreemptyitems%
  \readlist*\PfC@ListeInsulte{\%,!,§,\#,*,@,-}%
  \reademptyitems%
  \IfBooleanTF{#1}{%
    \MelangeListe{1,2,3,4,5,6,7}{5}%
  }{%
    \stepcounter{PfCNbInsulte}%
    \MelangeListe{1,2,3,4,5,6,7}{3}%
  }%
  \setsepchar{,}\ignoreemptyitems%
  \readlist*\PfC@ListeInsulteMelange{\faa}%
  \reademptyitems%
  \ifboolKV[TicketCaisse]{Solution}{\textcolor{PfCTicketCouleurSolution}{#2}}{%
    \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeInsulteMelangelen}}\do{%
      \edef\Titi{\PfC@ListeInsulteMelange[##1]}%
      \PfC@ListeInsulte[\Titi]%
    }%
  }%
}%

\NewDocumentCommand\PfC@PrixTicket{om}{%
  \ifboolKV[TicketCaisse]{CHF}{%
    \DeclareSIUnit{\Tempo}{\PfCCHF}%
  }{%
    \ifboolKV[TicketCaisse]{CFA}{%
      \DeclareSIUnit{\Tempo}{\PfCCFA}%
    }{%
      \ifboolKV[TicketCaisse]{CFP}{%
        \DeclareSIUnit{\Tempo}{\PfCCFP}%
      }{%
        \ifboolKV[TicketCaisse]{US}{%
          \DeclareSIUnit{\Tempo}{\Dollar}%
        }{%
          \ifboolKV[TicketCaisse]{UK}{%
            \DeclareSIUnit{\Tempo}{\LivreSterling}%
          }{%
            \ifboolKV[TicketCaisse]{Euro}{%
              \DeclareSIUnit{\Tempo}{\EuRo}%
            }{%
              \if@CHF%
                \setKV[TicketCaisse]{CHF}%
              \fi%
              \DeclareSIUnit{\Tempo}{\DeviseDefaut}%
            }%
          }%
        }%
      }%
    }%
  }%
  \IfInteger{#2}{%
    \ifboolKV[TicketCaisse]{CHF}{%
      \si{\PfCCHF}~\num{#2}.-%
    }{%
      \SI[round-mode=places,round-precision=2]{#2}{\Tempo}%
    }%
  }{%
    \SI[round-mode=places,round-precision=2]{#2}{\Tempo}%
  }%
}%

\setKVdefault[TicketCaisse]{Largeur=222pt,Especes=50,Simple=false,Taxes=false,SansRendu=false,Enseigne=Au comptoir des maths,DateAchat=\today,HeureAchat=15:13:34,Taches=false,Rendu,Total,SousTotal=false,UK=false,US=false,CFA=false,CFP=false,CHF=false,Euro=false,Solution=false,Couleur={},Service={},Unitaire=false,CB=false}%

\NewDocumentCommand\TicketCaisse{som}{%
  \setcounter{PfCNbInsulte}{0}%
  \useKVdefault[TicketCaisse]%
  \setKV[TicketCaisse]{#2}%
  \ifemptyKV[TicketCaisse]{Service}{}{\setKV[TicketCaisse]{Taxes}}%
  \ifemptyKV[TicketCaisse]{Couleur}{}{\colorlet{PfCTicketCouleurSolution}{\useKV[TicketCaisse]{Couleur}}\setKV[TicketCaisse]{Solution}}%
  \setlength{\PfCTicketLarg}{\useKV[TicketCaisse]{Largeur}}%
  \setsepchar[*]{,*/}%
  \readlist*\PfC@ListeAchats{#3}%
  % On fait trois 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 Elements
  \edef\PfC@FooElements{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \edef\PfC@FooElements{\PfC@FooElements,\PfC@ListeAchats[\compteurcnt,2]}%
  }%
  % Liste Prix Unitaire
  \edef\PfC@FooPUnitaires{}%
  \foreachitem\compteur\in\PfC@ListeAchats{%
    \StrChar{\PfC@ListeAchats[\compteurcnt,3]}{1}[\MyLetter]%
    \IfStrEqCase{\MyLetter}{%
      {!}{%
        \StrBehind{\PfC@ListeAchats[\compteurcnt,3]}{!}[\Titi]%
        \StrChar{\Titi}{1}[\Toto]%
        \IfStrEq{\Toto}{*}{%
          \StrBehind{\PfC@ListeAchats[\compteurcnt,3]}{!*}[\Tata]%
          \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires,\Tata}%
        }{%
          \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires,\Titi}%
        }%
      }% 
      {*}{\StrBehind{\PfC@ListeAchats[\compteurcnt,3]}{*}[\Titi]%
        \edef\PfC@FooPUnitaires{\PfC@FooPUnitaires,\Titi}}%
    }[\edef\PfC@FooPUnitaires{\PfC@FooPUnitaires,\PfC@ListeAchats[\compteurcnt,3]}]%
  }%
  % On les lit
  \setsepchar{,}\ignoreemptyitems%
  \readlist*\PfC@ListeQuantites{\PfC@FooQuantites}%
  \readlist*\PfC@ListeElements{\PfC@FooElements}%
  \readlist*\PfC@ListePUnitaires{\PfC@FooPUnitaires}%
  \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]}}%
  }%
  \ifboolKV[TicketCaisse]{Taxes}{%
    % On décompose la clé
    \StrChar{\useKV[TicketCaisse]{Service}}{1}[\MyLetter]%
    % Si le premier caractère est !, il faut regarder si le deuxième caractère est une étoile
    \IfStrEq{\MyLetter}{!}{%
      \StrChar{\useKV[TicketCaisse]{Service}}{2}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[TicketCaisse]{Service}}{2}[\PfC@TCValeurService]
        \setcounter{PfCChoixService}{3}%
      }{%
        \StrGobbleLeft{\useKV[TicketCaisse]{Service}}{1}[\PfC@TCValeurService]
        \setcounter{PfCChoixService}{1}%
      }%
    }{%il faut regarder si c'est une étoile
      \StrChar{\useKV[TicketCaisse]{Service}}{1}[\MyLettera]%
      \IfStrEq{\MyLettera}{*}{%
        \StrGobbleLeft{\useKV[TicketCaisse]{Service}}{1}[\PfC@TCValeurService]
        \setcounter{PfCChoixService}{2}
      }{%
        \edef\PfC@TCValeurService{\useKV[TicketCaisse]{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}}%
  }{}%
  % Le coût total est \PfC@TCTotal\\
  \IfBooleanTF{#1}{%
    \ttfamily
    \begin{tabular}{|m{0.48\PfCTicketLarg}m{0.13\PfCTicketLarg}m{0.165\PfCTicketLarg}m{0.225\PfCTicketLarg}|}%
      \hline
      &&&\\%
    \multicolumn{4}{|c|}{\Large\bfseries\useKV[TicketCaisse]{Enseigne}}\\%
    &&&\\%
    \hline%
    &&&\\%
    \footnotesize\sc Description&\centering \footnotesize\sc Qte.&\centering\footnotesize\sc P.u.&\hfill\footnotesize\sc Prix \ifboolKV[TicketCaisse]{Taxes}{H.T.}{Net}\\%
    &&&\\%
    \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeAchatslen}}\do{%
      \PfC@ListeElements[##1]&%
      \centering
        \footnotesize%
        \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
        \IfStrEq{\MyLetter}{!}{\PfC@PrixInsulte*{\PfC@ListeQuantites[##1]}}{\xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[TicketCaisse]{Unitaire}{\num{1}}{}}{\num{\PfC@ListeQuantites[##1]}}}%
      &
      \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,3]}{1}[\MyLettera]%
          % Si c'est un !, on affiche pas
          % Sinon, on affiche
          \IfStrEq{\MyLettera}{!}{%
            \PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}%
          }{%
            \xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[TicketCaisse]{Unitaire}{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}{}}{%
              \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
            }%
          }%
        }%
      &\hfill
        \StrChar{\PfC@ListeAchats[##1,3]}{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,3]}{2}[\MyLettera]%
          \IfStrEq{\MyLettera}{*}{%
            \PfC@PrixInsulte*{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}}%
          }{%
            \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}%
          }%
        }{%il faut regarder si c'est une étoile
          \StrChar{\PfC@ListeAchats[##1,3]}{1}[\MyLettera]%
          \IfStrEq{\MyLettera}{*}{%
            \PfC@PrixInsulte{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}}%
          }{%
            \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}%
          }%
        }%
      \\
    }%
    &&&\\%
      \hline%
      &&&\\
    % Partie Service
    \ifboolKV[TicketCaisse]{Taxes}{%
      Total H.T.\uppercase{&}\uppercase{&}\uppercase{&}\hfill\ifboolKV[TicketCaisse]{SousTotal}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotal}\else\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCSousTotal}}\fi}{\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCSousTotal}}}
      \\%
      Service %
      \ifodd\thePfCChoixService\relax \PfC@PrixInsulte{\num{\PfC@TCValeurService}}\else\num{\PfC@TCValeurService}\fi~\si{\percent}%
      &&&\hfill
        \ifnum\thePfCChoixService>1\relax \PfC@PrixInsulte{\PfC@PrixTicket{\PfC@TCService}}\else\PfC@PrixTicket{\PfC@TCService}\fi%
      \\
      &&&\\
      \hline
      &&&\\
    }{}%
    \ifboolKV[TicketCaisse]{Simple}{}{%
      Total\ifboolKV[TicketCaisse]{Taxes}{ T.T.C.}{}&&&\hfill\ifboolKV[TicketCaisse]{Total}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCTotal}\else\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCTotal}}\fi}{\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCTotal}}}\\%
      \ifboolKV[TicketCaisse]{SansRendu}{}{%
        \ifboolKV[TicketCaisse]{CB}{Carte}{Espèces}&&&\hfill\ifboolKV[TicketCaisse]{CB}{\PfC@PrixTicket{\PfC@TCTotal}}{\PfC@PrixTicket{\useKV[TicketCaisse]{Especes}}}\\%
        Rendu&&&\hfill\ifboolKV[TicketCaisse]{CB}{--}{\ifboolKV[TicketCaisse]{Rendu}{\PfC@PrixTicket{\fpeval{\useKV[TicketCaisse]{Especes}-\PfC@TCTotal}}}{\PfC@PrixInsulte*{\PfC@PrixTicket{\fpeval{\useKV[TicketCaisse]{Especes}-\PfC@TCTotal}}}}}\\%
      }
      &&&\\%
    }%
      \multicolumn{4}{|c|}{\footnotesize\useKV[TicketCaisse]{DateAchat}\qquad\useKV[TicketCaisse]{HeureAchat}}\\%
      \hline
    \end{tabular}
  }{%
  {\ttfamily%
    \begin{NiceTabular}{m{0.48\PfCTicketLarg}m{0.13\PfCTicketLarg}m{0.165\PfCTicketLarg}m{0.225\PfCTicketLarg}}%
      \CodeBefore
      \tikz\node[opacity=0.2,yshift=-1.5cm] at ($(1-|1)!0.5!(1-|last)$) {\Large\bfseries\reflectbox{
          \begin{tabular}{c}
            Papier garanti\\
            sans Phénol
          \end{tabular}
        }
      };
      \tikz\node[opacity=0.2,anchor=center,yshift=1cm] at ($(last-|1)!0.5!(last-|last)$) {\Large\bfseries\reflectbox{%
          \faRecycle~Pensez à trier.%
        }%
      };%
      \tikz\node[opacity=0.5,anchor=center,yshift=2cm] at ($(last-|1)!0.5!(last-|last)$) {\Large\bfseries\reflectbox{
          \LogoRecyclage[Couleur=0.8white]%
        }%
      };%
      \tikz\draw[fill=Ivory,opacity=0.5] (1-|1) rectangle (last-|last);%
    \Body
    &&&\\%
    \Block{1-4}{\Large\bfseries\useKV[TicketCaisse]{Enseigne}}&&&\\%
    \\%
    \Cdots\\%
    \\%
    \Block[l]{}{\footnotesize\sc Description}&\Block{}{\footnotesize\sc Qte.}&\Block{}{\footnotesize\sc P.u.}&\Block[r]{}{\footnotesize\sc Prix \ifboolKV[TicketCaisse]{Taxes}{H.T.}{Net}}\\%
    \\%
    \xintFor* ##1 in{\xintSeq{1}{\PfC@ListeAchatslen}}\do{%
      \PfC@ListeElements[##1]&%
      \Block{}{%
        \footnotesize%
        \StrChar{\PfC@ListeAchats[##1,1]}{1}[\MyLetter]%
        \IfStrEq{\MyLetter}{!}{\PfC@PrixInsulte*{\num{\PfC@ListeQuantites[##1]}}}{\xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[TicketCaisse]{Unitaire}{\num{1}}{}}{\num{\PfC@ListeQuantites[##1]}}}%
      }&
      \Block[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,3]}{1}[\MyLettera]%
          % Si c'est un !, on affiche pas
          % Sinon, on affiche
          \IfStrEq{\MyLettera}{!}{%
            \PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}%
          }{%
            \xintifboolexpr{\fpeval{\PfC@ListeQuantites[##1]}==1}{\ifboolKV[TicketCaisse]{Unitaire}{\PfC@PrixTicket{\PfC@ListePUnitaires[##1]}}{}}{%
              \PfC@PrixTicket{\PfC@ListePUnitaires[##1]}%
            }%
          }%
        }%
      }%
      &\Block[r]{}{%
        \StrChar{\PfC@ListeAchats[##1,3]}{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,3]}{2}[\MyLettera]%
          \IfStrEq{\MyLettera}{*}{%
            \PfC@PrixInsulte*{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}}%
          }{%
            \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}%
          }%
        }{%il faut regarder si c'est une étoile
          \StrChar{\PfC@ListeAchats[##1,3]}{1}[\MyLettera]%
          \IfStrEq{\MyLettera}{*}{%
            \PfC@PrixInsulte{\PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}}%
          }{%
            \PfC@PrixTicket{\fpeval{\PfC@ListeQuantites[##1]*\PfC@ListePUnitaires[##1]}}%
          }%
        }%
      }\\
    }%
    \\%
    \Cdots\\%
    % Partie Service
    \ifboolKV[TicketCaisse]{Taxes}{%
      Total H.T.&&&\Block[r]{}{\ifboolKV[TicketCaisse]{SousTotal}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCSousTotal}\else\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCSousTotal}}\fi}{\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCSousTotal}}}
      }\\%
      Service %
      \ifodd\thePfCChoixService\relax \PfC@PrixInsulte{\num{\PfC@TCValeurService}}\else\num{\PfC@TCValeurService}\fi~\si{\percent}%
      &&&\Block[r]{}{%
        \ifnum\thePfCChoixService>1\relax \PfC@PrixInsulte{\PfC@PrixTicket{\PfC@TCService}}\else\PfC@PrixTicket{\PfC@TCService}\fi%
      }\\
      \Cdots\\
      \\
    }{}%
    \ifboolKV[TicketCaisse]{Simple}{}{%
      Total\ifboolKV[TicketCaisse]{Taxes}{ T.T.C.}{}&&&\Block[r]{}{\ifboolKV[TicketCaisse]{Total}{\ifnum\thePfCNbInsulte=0\relax\PfC@PrixTicket{\PfC@TCTotal}\else\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCTotal}}\fi}{\PfC@PrixInsulte*{\PfC@PrixTicket{\PfC@TCTotal}}}}\\%
      \ifboolKV[TicketCaisse]{SansRendu}{}{%
        \ifboolKV[TicketCaisse]{CB}{
          CB&&&\Block[r]{}{\PfC@PrixTicket{\PfC@TCTotal}}\\%
          Rendu&&&\Block[r]{}{--}
        }{%
        Espèces&&&\Block[r]{}{\PfC@PrixTicket{\useKV[TicketCaisse]{Especes}}}\\%
        Rendu&&&\Block[r]{}{\ifboolKV[TicketCaisse]{Rendu}{\PfC@PrixTicket{\fpeval{\useKV[TicketCaisse]{Especes}-\PfC@TCTotal}}}{\PfC@PrixInsulte*{\PfC@PrixTicket{\fpeval{\useKV[TicketCaisse]{Especes}-\PfC@TCTotal}}}}}}\\%
      }
      \\%
    }%
    \Block{1-4}{\footnotesize\useKV[TicketCaisse]{DateAchat}\qquad\useKV[TicketCaisse]{HeureAchat}}&&&\\%
    \end{NiceTabular}
  }%
  }
}%
\makeatother