nc.noumea.mairie.appock.services.impl.MailServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for nc.noumea.mairie.appock.services.impl.MailServiceImpl.java

Source

package nc.noumea.mairie.appock.services.impl;

/*-
 * #%L
 * Logiciel de Gestion des approvisionnements et des stocks des fournitures administratives de la Mairie de Nouma
 * %%
 * Copyright (C) 2017 Mairie de Nouma, Nouvelle-Caldonie
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */

import nc.noumea.mairie.appock.core.security.AppUser;
import nc.noumea.mairie.appock.core.utility.AppockMail;
import nc.noumea.mairie.appock.core.utility.DateUtil;
import nc.noumea.mairie.appock.dto.ArticleSpecifique;
import nc.noumea.mairie.appock.entity.*;
import nc.noumea.mairie.appock.entity.CommandeService;
import nc.noumea.mairie.appock.entity.Service;
import nc.noumea.mairie.appock.enums.Role;
import nc.noumea.mairie.appock.repositories.AppUserRepository;
import nc.noumea.mairie.appock.services.*;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.util.CollectionUtils;

import javax.activation.DataHandler;
import javax.annotation.PostConstruct;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * Service de gestion des mails.
 */
@org.springframework.stereotype.Service("mailService")
@Scope(value = "singleton", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MailServiceImpl implements MailService {

    private static Logger log = LoggerFactory.getLogger(MailServiceImpl.class);

    @Autowired(required = false)
    Session mailServer;

    @Autowired(required = true)
    Boolean mailServerModeProduction;

    @Autowired
    ConfigService configService;

    @Autowired
    AuthHelper authHelper;

    @Autowired
    AppUserService appUserService;

    @Autowired
    AppUserRepository appUserRepository;

    @Autowired
    CommandeServiceService commandeServiceService;

    @Autowired
    ArticleCatalogueService articleCatalogueService;

    @Autowired
    CatalogueService catalogueService;

    @Autowired
    ServiceService serviceService;

    @PostConstruct
    public void initialize() {
        // #7763
        log.warn("mailServerModeProduction = " + mailServerModeProduction + " : " + //
                (mailServerModeProduction ? "tous les mails vont partir vers les VRAIS destinataires"
                        : "les mails vont partir vers la PERSONNE CONNECTEE"));
    }

    @Override
    public Message sendMail(AppockMail appockMail) throws MessagingException {

        if (CollectionUtils.isEmpty(appockMail.getListeDestinataire())) {
            log.warn("Mail non envoy, liste des destinataires vide : " + appockMail);
            return null;
        }

        MimeMessage msg = new MimeMessage(mailServer);
        msg.setFrom(appockMail.getFrom() != null ? appockMail.getFrom() : defaultFrom());

        String prefixeSujet = isModeProduction() ? "" : "[TEST APPOCK] ";
        msg.setSubject(prefixeSujet + appockMail.getSujet(), configService.getEncodageSujetEmail());

        StringBuilder infoAdditionnelle = new StringBuilder();

        for (InternetAddress adresse : appockMail.getListeDestinataire()) {
            if (isModeProduction()) {
                // on est en production, envoi rel de mail au destinataire
                msg.addRecipient(Message.RecipientType.TO, adresse);
            } else {
                // en test, on envoie le mail  la personne connecte
                InternetAddress adresseTesteur = getAdresseMailDestinataireTesteur();
                if (adresseTesteur != null) {
                    msg.addRecipient(Message.RecipientType.TO, adresseTesteur);
                }
                List<String> listeAdresseMail = new ArrayList<>();
                for (InternetAddress internetAddress : appockMail.getListeDestinataire()) {
                    listeAdresseMail.add(internetAddress.getAddress());
                }
                infoAdditionnelle.append("En production cet email serait envoy vers ")
                        .append(StringUtils.join(listeAdresseMail, ", ")).append("<br/><hr/>");
                break;
            }
        }

        String contenuFinal = "";
        if (!StringUtils.isBlank(infoAdditionnelle.toString())) {
            contenuFinal += "<font face=\"arial\" >" + infoAdditionnelle.toString() + "</font>";
        }

        contenuFinal += "<font face=\"arial\" >" + appockMail.getContenu() + "<br/><br/></font>"
                + configService.getPiedDeMail();

        gereBonLivraisonDansMail(appockMail, msg, contenuFinal);

        if (!ArrayUtils.isEmpty(msg.getAllRecipients())) {
            Transport.send(msg);
        }

        return msg;
    }

    private void gereBonLivraisonDansMail(AppockMail appockMail, MimeMessage msg, String contenuFinal)
            throws MessagingException {
        if (appockMail.getBonLivraison() == null) {
            msg.setContent(contenuFinal, "text/html; charset=utf-8");
        } else {
            BonLivraison bonLivraison = appockMail.getBonLivraison();
            Multipart multipart = new MimeMultipart();
            BodyPart attachmentBodyPart = new MimeBodyPart();

            File file = commandeServiceService.getFileBonLivraison(appockMail.getBonLivraison());

            ByteArrayDataSource bds = null;
            try {
                bds = new ByteArrayDataSource(Files.readAllBytes(file.toPath()),
                        bonLivraison.getMimeType().getLibelle());
            } catch (IOException e) {
                e.printStackTrace();
            }

            attachmentBodyPart.setDataHandler(new DataHandler(bds));
            attachmentBodyPart.setFileName(bonLivraison.getNomFichier());
            multipart.addBodyPart(attachmentBodyPart);

            BodyPart htmlBodyPart = new MimeBodyPart();
            htmlBodyPart.setContent(contenuFinal, "text/html; charset=utf-8");
            multipart.addBodyPart(htmlBodyPart);
            msg.setContent(multipart);
        }
    }

    /**
     * @return true si on est en mode production : les mails doivent partir vers les vrais destinataires, false en mode "test" (ou recette) : les mails partent
     * vers la personne connecte
     */
    private boolean isModeProduction() {
        if (mailServerModeProduction == null) {
            log.error("mailServerModeProduction n'est pas dfini !");
            return false;
        }
        log.debug("mail mode production = " + mailServerModeProduction);
        return mailServerModeProduction;
    }

    /**
     * @return l'adresse mail du testeur (en mode non production), null si la personne connecte n'a pas d'email renseign ou s'il n'y a personne de connect
     * (ex : cas d'un job quartz)
     * @throws AddressException
     */
    private InternetAddress getAdresseMailDestinataireTesteur() throws AddressException {
        AppUser currentUser = authHelper.getCurrentUser();
        if (currentUser == null) {
            return null; // pas de personne connecte => pas de destinataire testeur
        }
        String email = currentUser.getEmail();
        return StringUtils.isNotBlank(email) ? new InternetAddress(email) : null;
    }

    private InternetAddress defaultFrom() throws AddressException {
        return new InternetAddress(configService.getDefaultFromEmailAddress());
    }

    @Override
    public void sendMailSuiteDesactivationArticleCataloguePanier(ArticleCatalogue articleCatalogue,
            List<AppUser> listeAppUser) throws UnsupportedEncodingException, MessagingException {
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(listeAppUser);
        appockMail.setSujet("[APPOCK] Article retir de votre panier");

        appockMail.setContenu("" + "Bonjour,<br/><br/>" + "L'article '" + articleCatalogue.getLibelle() + "' ( "
                + articleCatalogue.getReference()
                + ") a t dsactiv dans le catalogue. Cet article se trouvait dans le panier de votre service, celui-ci a t retir automatiquement de votre panier.");

        sendMail(appockMail);
    }

    @Override
    public void sendMailSuiteDesactivationArticleCatalogueDemande(ArticleCatalogue articleCatalogue,
            Demande demande, List<AppUser> listeAppUser) throws UnsupportedEncodingException, MessagingException {
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(listeAppUser);
        appockMail.setSujet("[APPOCK] Article dsactiv prsent dans la demande N " + demande.getNumero());

        appockMail.setContenu("" + "Bonjour,<br/><br/>" + "L'article '" + articleCatalogue.getLibelle() + "' ( "
                + articleCatalogue.getReference()
                + ") a t dsactiv dans le catalogue. Cet article se trouvait dans la demande N "
                + demande.getNumero()
                + " de votre service.<br/>Cet article ne pourra pas tre command, merci de le remplacer par un autre article.");

        sendMail(appockMail);
    }

    @Override
    public void sendMailSuiteTransmissionDemande(Demande demande)
            throws MessagingException, UnsupportedEncodingException {
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserService.findAllWithRole(Role.ROLE_REFERENT_ACHAT, true));
        appockMail.setSujet("[APPOCK] Nouvelle demande  traiter - N " + demande.getNumero());
        appockMail.setContenu(
                demande.getTransmetUser() + " du service " + demande.getService().getLibellePoleDirectionService()
                        + " vient de transmettre une nouvelle demande d'approvisionnement N "
                        + demande.getNumero() + ".<br/>Merci de procder au traitement de cette demande.");
        sendMail(appockMail);
    }

    @Override
    public void sendMailSuiteTraitementDemande(Demande demande)
            throws MessagingException, UnsupportedEncodingException {
        AppockMail appockMail = initAppockMailAvecReferentService(demande);

        if (appockMail == null)
            return;

        appockMail.setSujet(
                "[APPOCK] Traitement de votre demande N " + demande.getNumero() + " par la section achat");

        appockMail.setContenu(
                "" + "Bonjour,<br/><br/>" + demande.getTraitementUser() + " vient de traiter votre demande N "
                        + demande.getNumero() + ". Voici ci-dessous le rapport de ce traitement.<br/><br/>"
                        + construiTableauHtmlRapportTraitementDemande(demande));

        sendMail(appockMail);
    }

    @Override
    public void sendMailSuiteAnnulationDemande(Demande demande)
            throws MessagingException, UnsupportedEncodingException {
        AppockMail appockMail = initAppockMailAvecReferentService(demande);

        if (appockMail == null)
            return;

        appockMail.setSujet(
                "[APPOCK] Annulation de votre demande N " + demande.getNumero() + " par la section achat");
        appockMail.setContenu("" + "Bonjour,<br/><br/>La section achat vient d'annuler votre demande.");

        sendMail(appockMail);
    }

    @Override
    public void sendMailSuiteMiseAJourStock(List<Object[]> listeNouveauArticleStockAvecQuantite,
            List<Object[]> listeExistantArticleStockAvecQuantite, CommandeService commandeService)
            throws MessagingException, UnsupportedEncodingException {

        AppockMail appockMail = initAppockMailAvecReferentService(commandeService);
        AppUser appUser = authHelper.getCurrentUser();

        if (appockMail == null)
            return;

        appockMail.setSujet(
                "[APPOCK] Mise  jour du stock de votre service suite  la rception de la commande N "
                        + commandeService.getCommande().getNumero() + " par le service achat");

        appockMail.setContenu("" + "Bonjour,<br/><br/>" + appUser.getNomComplet()
                + " vient de valider la livraison de votre demande. Voici ci-dessous les mises  jour de votre stock en fonction de cette livraison :<br/><br/>"
                + construiTableauHtmlRapportStock(listeNouveauArticleStockAvecQuantite,
                        listeExistantArticleStockAvecQuantite));

        sendMail(appockMail);

    }

    private AppockMail initAppockMailAvecReferentService(Demande demande) throws UnsupportedEncodingException {
        return initAppockMailAvecReferentService(demande.getTransmetLogin());
    }

    private AppockMail initAppockMailAvecReferentService(CommandeService commandeService)
            throws UnsupportedEncodingException {
        return initAppockMailAvecReferentService(commandeService.getReceptionLogin());
    }

    private AppockMail initAppockMailAvecReferentService(String loginReferent) throws UnsupportedEncodingException {
        AppockMail appockMail = new AppockMail();
        AppUser appUser = appUserService.findByLogin(loginReferent);
        if (appUser == null) {
            return null;
        }

        if (!appUser.isTitulaire()) {
            // Si ce n'est pas le titulaire, on envoie aussi au titulaire
            AppUser appUserTitulaire = appUserService.findTitulaireByService(appUser.getService());
            if (appUserTitulaire != null) {
                appockMail.addDestinataire(appUserTitulaire);
            }
        }

        appockMail.addDestinataire(appUser);

        return appockMail;
    }

    private String construiTableauHtmlRapportTraitementDemande(Demande demande) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<table style=\"border-collapse: collapse;\">");
        sb.append("<tr bgcolor=\"#7FBFFF\">");
        sb.append(createTh("Rfrence"));
        sb.append(createTh("Libell"));
        sb.append(createTh("Demand"));
        sb.append(createTh("Valid"));
        sb.append(createTh("Colisage"));
        sb.append(createTh("Quantit relle"));
        sb.append(createTh("Action section achat"));
        sb.append("</tr>");

        for (ArticleDemande articleDemande : demande.getListeArticleDemande()) {
            String bgColor = null;
            if (articleDemande.isValide()) {
                if (!articleDemande.getQuantite().equals(articleDemande.getQuantiteCommande())) {
                    bgColor = "#FAAC58";
                }
            }
            if (articleDemande.isAjoutReferentAchat()) {
                bgColor = "#0D8781";
            }
            if (articleDemande.isRejete()) {
                bgColor = "#FA5858";
            }

            if (StringUtils.isNotBlank(bgColor)) {
                sb.append("<tr bgcolor=\"").append(bgColor).append("\">");
            } else {
                sb.append("<tr>");
            }

            sb.append(createTd(articleDemande.getArticleCatalogue().getReference(), false));
            sb.append(createTd(articleDemande.getArticleCatalogue().getLibelle(), false));
            sb.append(
                    createTd(articleDemande.isAjoutReferentAchat() ? articleDemande.getQuantiteCommande().toString()
                            : articleDemande.getQuantite().toString(), true));
            sb.append(createTd(articleDemande.isValide() ? articleDemande.getQuantiteCommande().toString() : "0",
                    true));
            sb.append(createTd(articleDemande.getArticleCatalogue().getLibelleColisage(), false));
            sb.append(createTd(
                    articleDemande.isValide() ? articleDemande.getQuantiteReelCommande().toString() : "0", true));

            String libelleEtat = articleDemande.getEtatArticleDemande().getLibelle();
            if (articleDemande.isAjoutReferentAchat()) {
                libelleEtat = "Ajout";
            }

            sb.append(createTd(libelleEtat, true));
            sb.append("<tr>");
        }

        sb.append("</table>");

        return sb.toString();
    }

    private String createTh(String value) {
        return "<th style=\"border: 1px solid black;\">" + value + "</th>";
    }

    private String createTd(String value, boolean center) {
        return "<td style=\"border: 1px solid black;\"" + (center ? " align=\"center\"" : "") + ">" + value
                + "</td>";
    }

    @Override
    public void sendMailSuiteReceptionCommandeService(CommandeService commandeService)
            throws MessagingException, UnsupportedEncodingException {
        String libelleService = commandeService.getService().getLibellePoleDirectionService();
        String numeroCommande = commandeService.getCommande().getNumero();
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserService.findAllWithRole(Role.ROLE_REFERENT_ACHAT, true));
        appockMail.setSujet(
                "[APPOCK] Rception de la commande N " + numeroCommande + " par le service " + libelleService);

        String contenu = "Bonjour,<br/><br/>" + commandeService.getReceptionUser() + " du service " + libelleService
                + " vient de rceptionner la commande N " + numeroCommande
                + ". Voici ci-dessous le rapport de rception :<br/><br/>"
                + construiTableauHtmlRapportReceptionCommandeService(commandeService);
        appockMail.setBonLivraison(commandeService.getBonLivraison());

        if (StringUtils.isNotBlank(commandeService.getCommentaire())) {
            contenu += "<br/>Le rfrent service vous joint le commentaire suivant :<br/>\"<i>"
                    + commandeService.getCommentaire() + "\"</i><br/>";
        }

        contenu += "<br/>Veuillez trouver en pice jointe le bordereau de livraison.";

        appockMail.setContenu(contenu);

        sendMail(appockMail);
    }

    private String construiTableauHtmlRapportReceptionCommandeService(CommandeService commandeService) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<table style=\"border-collapse: collapse;\">");
        sb.append("<tr bgcolor=\"#7FBFFF\">");
        sb.append(createTh("Rfrence"));
        sb.append(createTh("Libell"));
        sb.append(createTh("Quantit reue"));
        sb.append(createTh("Quantit commande"));
        sb.append(createTh("Colisage"));
        sb.append(createTh("Quantit relle reue"));
        sb.append(createTh("Quantit relle commande"));
        sb.append("</tr>");

        for (ArticleCommande articleCommande : commandeService.getListeArticleCommande()) {
            sb.append("<tr>");
            sb.append(createTd(articleCommande.getArticleCatalogue().getReference(), false));
            sb.append(createTd(articleCommande.getArticleCatalogue().getLibelle(), false));
            sb.append(createTd(articleCommande.getQuantiteRecu().toString(), true));
            sb.append(createTd(articleCommande.getQuantiteCommande().toString(), true));
            sb.append(createTd(articleCommande.getArticleCatalogue().getLibelleColisage(), false));
            sb.append(createTd(articleCommande.getQuantiteReelRecu().toString(), true));
            sb.append(createTd(articleCommande.getQuantiteReelCommande().toString(), true));
            sb.append("<tr>");
        }

        sb.append("</table>");

        return sb.toString();
    }

    private String construiTableauHtmlArticleSpecifique(ArticleSpecifique articleSpecifique) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<table style=\"border-collapse: collapse;\">");
        sb.append("<tr bgcolor=\"#7FBFFF\">");
        sb.append(createTh("Sous-famille"));
        sb.append(createTh("Rfrence"));
        sb.append(createTh("Libell"));
        sb.append(createTh("Fournisseur"));
        sb.append(createTh("Colisage"));
        sb.append(createTh("Quantit demande"));
        sb.append(createTh("Quantit relle"));
        sb.append("</tr>");

        sb.append(createTdArticleSpecifique(articleSpecifique));

        sb.append("</table>");

        return sb.toString();
    }

    private String createTdArticleSpecifique(ArticleSpecifique articleSpecifique) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<tr>");
        sb.append(createTd(
                articleSpecifique.getSousFamille() != null ? articleSpecifique.getSousFamille().getLibelle() : "",
                true));
        sb.append(createTd(articleSpecifique.getReference(), true));
        sb.append(createTd(articleSpecifique.getLibelle(), true));
        sb.append(createTd(
                articleSpecifique.getFournisseur() != null ? articleSpecifique.getFournisseur().getNom() : "",
                true));
        sb.append(createTd(articleSpecifique.getLibelleColisage(), true));
        sb.append(createTd(articleSpecifique.getQuantite().toString(), true));
        sb.append(createTd(articleSpecifique.getQuantiteReel().toString(), true));
        sb.append("<tr>");

        return sb.toString();
    }

    private String construiTableauHtmlRapportStock(List<Object[]> listeNouveauArticleStockAvecQuantite,
            List<Object[]> listeExistantArticleStockAvecQuantite) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<table style=\"border-collapse: collapse;\">");
        sb.append("<tr bgcolor=\"#7FBFFF\">");
        sb.append(createTh("Rfrence"));
        sb.append(createTh("Libell"));
        sb.append(createTh("Quantit ajoute au stock"));
        sb.append(createTh("Nouvelle quantit dans le stock"));
        sb.append(createTh("Observation"));
        sb.append("</tr>");

        Catalogue catalogueActif = catalogueService.findActif();

        for (Object[] articleEtQuantite : listeNouveauArticleStockAvecQuantite) {
            sb.append(createTdGenericStock(catalogueActif, articleEtQuantite, "Nouvel article en stock"));
        }

        for (Object[] articleEtQuantite : listeExistantArticleStockAvecQuantite) {
            sb.append(createTdGenericStock(catalogueActif, articleEtQuantite, "Quantit du stock mise  jour"));
        }

        sb.append("</table>");

        return sb.toString();
    }

    private String createTdGenericStock(Catalogue catalogue, Object[] articleEtQuantite, String observation) {
        ArticleStock articleStock = ((ArticleStock) articleEtQuantite[0]);
        ArticleCatalogue articleCatalogue = articleCatalogueService
                .findArticleCataloguePlusRecentParReference(articleStock.getReferenceArticleStock(), catalogue);
        StringBuilder sb = new StringBuilder("");
        sb.append("<tr>");
        sb.append(createTd(articleStock.getReferenceArticleStock(), false));
        sb.append(createTd(articleCatalogue.getLibelle(), false));
        sb.append(createTd(articleEtQuantite[1].toString(), true));
        sb.append(createTd(articleStock.getQuantiteStock().toString(), true));
        sb.append(createTd(observation, true));
        sb.append("<tr>");

        return sb.toString();
    }

    @Override
    public void sendMailDemandeSpecifique(ArticleSpecifique articleSpecifique)
            throws UnsupportedEncodingException, MessagingException {
        AppUser currentUser = authHelper.getCurrentUser();

        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserService.findAllWithRole(Role.ROLE_REFERENT_ACHAT, true));

        // On ajoute en destinaitaire la personne connecte et le titulaire du service (si ce n'est pas lui mme)
        if (!currentUser.isTitulaire()) {
            // Si ce n'est pas le titulaire, on envoi aussi au titulaire
            AppUser appUserTitulaire = appUserService.findTitulaireByService(currentUser.getService());
            if (appUserTitulaire != null) {
                appockMail.addDestinataire(appUserTitulaire);
            }
        }

        appockMail.addDestinataire(currentUser);

        appockMail.setSujet("[APPOCK] Demande d'article spcifique");

        String contenu = "Bonjour,<br/><br/>" + currentUser.getNomComplet() + " du service "
                + currentUser.getService().getLibellePoleDirectionService()
                + " vous fait parvenir la demande d'article spcifique suivante :<br/><br/>"
                + construiTableauHtmlArticleSpecifique(articleSpecifique);

        if (StringUtils.isNotBlank(articleSpecifique.getObservation())) {
            contenu += "<br/>Motivation jointe  la demande :<br/>\"<i>" + articleSpecifique.getObservation()
                    + "\"</i>";
        }

        appockMail.setContenu(contenu);

        sendMail(appockMail);
    }

    @Override
    public void sendMailDemandeInventaire(Service service) throws UnsupportedEncodingException, MessagingException {
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserRepository.findAllByService(service));
        appockMail.setSujet("[APPOCK] Demande d'inventaire pour mise  jour de votre stock");
        String contenu = "Bonjour,<br/><br/>La section achat vous invite  faire un inventaire de votre stock.<br/>Rendez-vous sur l'application APPOCK (menu 'Mon stock') pour procder  des ajustements de votre stock, avec la contribution de la section achat si ncessaire. Cliquez ensuite sur le bouton 'Valider l'inventaire'.";
        appockMail.setContenu(contenu);
        sendMail(appockMail);
    }

    @Override
    public void sendMailValidationInventaire(Service service)
            throws UnsupportedEncodingException, MessagingException {
        AppUser currentUser = authHelper.getCurrentUser();
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserService.findAllWithRole(Role.ROLE_REFERENT_ACHAT, true));
        appockMail.setSujet(
                "[APPOCK] Validation de l'inventaire du service " + service.getLibellePoleDirectionService());
        String contenu = "Bonjour,<br/><br/>" + currentUser.getNomComplet() + " du service "
                + service.getLibellePoleDirectionService()
                + " vient de valider son inventaire. Voici ci-dessous l'tat actuel de son stock :<br/><br/>"
                + construiTableauHtmlStockService(service);
        appockMail.setContenu(contenu);
        sendMail(appockMail);
    }

    @Override
    public void sendMailEcheanceCommandeParReferentAchat(LocalDate datePrevisionnelleCommande)
            throws MessagingException, UnsupportedEncodingException {
        AppockMail appockMail = new AppockMail();
        appockMail.addDestinataire(appUserService.findAllWithRole(Role.ROLE_REFERENT_SERVICE, true));
        appockMail.setSujet("[APPOCK] Rappel d'chance de commande");
        String contenu = "Bonjour,<br/><br/>Une commande est prvue le <b>"
                + (datePrevisionnelleCommande == null ? "?"
                        : DateUtil.formatDate(datePrevisionnelleCommande.atStartOfDay()))
                + "</b> par les rfrents achat. Veuillez envoyer vos demandes d'approvisionnement au plus tard  cette date.";
        appockMail.setContenu(contenu);
        sendMail(appockMail);
    }

    private String construiTableauHtmlStockService(Service service) {
        StringBuilder sb = new StringBuilder("");
        sb.append("<table style=\"border-collapse: collapse;\">");
        sb.append("<tr bgcolor=\"#7FBFFF\">");
        sb.append(createTh("Rfrence"));
        sb.append(createTh("Libell"));
        sb.append(createTh("En stock"));
        sb.append("</tr>");

        service = serviceService.findOneAndChargeElementStock(service.getId());

        for (ArticleStock articleStock : service.getStock().getListeArticleStock()) {
            sb.append("<tr>");
            sb.append(createTd(articleStock.getReferenceArticleStock(), false));
            sb.append(createTd(articleStock.getArticleCatalogue().getLibelle(), false));
            sb.append(createTd(articleStock.getQuantiteStock().toString(), true));
            sb.append("</tr>");
        }

        sb.append("</table>");

        return sb.toString();
    }
}