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

Java tutorial

Introduction

Here is the source code for nc.noumea.mairie.appock.services.impl.CommandeServiceImpl.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 java.time.LocalDateTime;
import java.util.*;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;

import nc.noumea.mairie.appock.comparator.ArticleDemandeComparator;
import nc.noumea.mairie.appock.core.entity.AbstractEntity;
import nc.noumea.mairie.appock.core.security.AppUser;
import nc.noumea.mairie.appock.core.services.impl.GenericServiceImpl;
import nc.noumea.mairie.appock.core.utility.AppockUtil;
import nc.noumea.mairie.appock.entity.*;
import nc.noumea.mairie.appock.enums.EtatCommande;
import nc.noumea.mairie.appock.enums.EtatDemande;
import nc.noumea.mairie.appock.enums.TypeCommandeNode;
import nc.noumea.mairie.appock.repositories.CommandeRepository;
import nc.noumea.mairie.appock.repositories.CommandeServiceRepository;
import nc.noumea.mairie.appock.repositories.DemandeRepository;
import nc.noumea.mairie.appock.services.AuthHelper;
import nc.noumea.mairie.appock.services.CatalogueService;
import nc.noumea.mairie.appock.services.DemandeService;
import nc.noumea.mairie.appock.util.CommandeTreeNode;
import nc.noumea.mairie.appock.util.FakeEntity;

@org.springframework.stereotype.Service("commandeService")
@Scope(value = "singleton", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Transactional
public class CommandeServiceImpl extends GenericServiceImpl<Commande>
        implements nc.noumea.mairie.appock.services.CommandeService {

    @Autowired
    CommandeRepository commandeRepository;

    @Autowired
    DemandeRepository demandeRepository;

    @Autowired
    CatalogueService catalogueService;

    @Autowired
    AuthHelper authHelper;

    @Autowired
    DemandeService demandeService;

    @Autowired
    CommandeServiceRepository commandeServiceRepository;

    @Override
    public CrudRepository getRepository() {
        return commandeRepository;
    }

    @Override
    public Commande findOne(Long id) {
        Commande commande = commandeRepository.findOne(id);

        AppockUtil.chargeCollection(commande.getListeDemande());
        AppockUtil.chargeCollection(commande.getListeCommandeService());

        chargeListeDemandeOf(commande);

        for (CommandeService commandeService : commande.getListeCommandeService()) {
            AppockUtil.chargeCollection(commandeService.getListeArticleCommande());
            AppockUtil.chargeElement(commandeService.getService());
            AppockUtil.chargeElement(commandeService.getService().getDirection());
            AppockUtil.chargeElement(commandeService.getService().getDirection().getPole());
        }

        return commande;
    }

    @Override
    public List<Commande> findAllEnAttenteReception() {
        List<Commande> result = commandeRepository
                .findAllByEtatCommandeOrderByDateCreationDesc(EtatCommande.EN_ATTENTE_RECEPTION_COMMANDE);
        result.forEach(this::chargeListeDemandeOf);
        return result;
    }

    @Override
    public Commande creeCommandeFromListeDemande(List<Demande> listeDemande) {
        if (CollectionUtils.isEmpty(listeDemande)) {
            return null;
        }
        AppUser currentUser = authHelper.getCurrentUser();

        Commande commande = new Commande();
        commande.setCreateUser(currentUser.getNomComplet());
        commande.setNumero(findNextNumero());

        return ajouteListeDemandeACommande(commande, listeDemande);
    }

    @Override
    public Commande ajouteListeDemandeACommande(Commande commande, List<Demande> listeDemande) {
        // On recharge depuis la base car la commande passe en paramtre vient d'une liste droulante qui n'est pas initialise
        if (commande.getId() != null) {
            commande = commandeRepository.findOne(commande.getId());
        }

        for (Demande demande : listeDemande) {
            // On rcupre chaque demande depuis la base pour ne pas avoir de soucis hibernate
            Demande demandeCommande = demandeRepository.findOne(demande.getId());
            demandeCommande.setCommande(commande);
            demandeCommande.setEtatDemande(EtatDemande.EN_COURS_COMMANDE);
            commande.getListeDemande().add(demandeCommande);
        }

        return save(commande);
    }

    private String findNextNumero() {
        String prefixe = LocalDateTime.now().getYear() + "-";
        Commande commande = commandeRepository.findTopByNumeroStartingWithOrderByNumeroDesc(prefixe);
        int numero = 1;
        if (commande != null) {
            numero = Integer
                    .parseInt(commande.getNumero().substring(prefixe.length(), commande.getNumero().length())) + 1;
        }
        return prefixe + StringUtils.leftPad(String.valueOf(numero), 4, "0");
    }

    @Override
    public CommandeTreeNode getCommandeEnAttenteReceptionTreeRoot(Commande commande) {
        CommandeTreeNode result = new CommandeTreeNode(null, "", null, null, null, 0, null);

        for (CommandeService commandeService : commande.getListeCommandeService()) {
            CommandeTreeNode rootService = new CommandeTreeNode(result,
                    commandeService.getService().getLibellePoleDirectionService(),
                    commandeService.getService().getId(), null, commandeService,
                    commandeService.getListeArticleCommande().size(), TypeCommandeNode.SERVICE);
            rootService.setReceptionne(commandeService.isReceptionne());
            rootService.setValide(commandeService.isValide());
            rootService.setReceptionUser(commandeService.getReceptionUser());
            rootService.setReceptionDateAsString(commandeService.getDatePassageReceptionAsString());
            result.appendChild(rootService);
        }

        return result;
    }

    @Override
    public CommandeTreeNode getCommandeTreeRoot(Commande commande, boolean vueAgrege) {
        CommandeTreeNode result = new CommandeTreeNode(null, "", null, null, null, 0, null);

        Map<Service, List<Demande>> map = construitMapServiceListeDemande(commande);

        List<Service> listeService = new ArrayList(map.keySet());
        Comparator serviceComparator = Comparator
                .comparing((Service service) -> service.getDirection().getPole().getLibelle())
                .thenComparing(service -> service.getDirection().getLibelleCourt())
                .thenComparing(Service::getLibelleCourt);
        Collections.sort(listeService, serviceComparator);

        for (Service service : listeService) {
            CommandeTreeNode rootService = construitPremierNiveauService(result, map, service, vueAgrege);

            if (!vueAgrege) {
                for (Demande demande : map.get(service)) {
                    rootService.appendChild(construitSecondNiveauDemande(result, demande));
                }
            }

            result.appendChild(rootService);
        }
        return result;
    }

    private CommandeTreeNode construitPremierNiveauService(CommandeTreeNode root, Map<Service, List<Demande>> map,
            Service service, boolean vueAgrege) {
        int nombreArticleService = 0;
        int prixTotalCommande = 0;

        if (vueAgrege) {
            List<Demande> listeDemande = map.get(service);
            for (Demande demande : listeDemande) {
                prixTotalCommande += demande.getPrixTotalCommande();
            }
            nombreArticleService = construitListeArticleDemandeQuantiteAgrege(listeDemande).size();
        } else {
            for (Demande demande : map.get(service)) {
                prixTotalCommande += demande.getPrixTotalCommande();
                for (ArticleDemande articleDemande : demande.getListeArticleDemande()) {
                    if (articleDemande.isValide()) {
                        nombreArticleService += 1;
                    }
                }
            }
        }

        return new CommandeTreeNode(root, service.getLibellePoleDirectionService(), service.getId(),
                prixTotalCommande, service, nombreArticleService, TypeCommandeNode.SERVICE);
    }

    @Override
    public List<ArticleDemande> construitListeArticleDemandeQuantiteAgrege(List<Demande> listeDemande) {

        Map<ArticleCatalogue, ArticleDemande> mapArticleCatalogueArticleDemande = new HashMap<>();

        for (Demande demande : listeDemande) {
            // On recr de nouveaux ArticleDemande pour ne pas modifier ceux de la liste initiale
            demande.getListeArticleDemande().stream().filter(ArticleDemande::isValide).forEach(articleDemande -> {
                // On recr de nouveaux ArticleDemande pour ne pas modifier ceux de la liste initiale
                ArticleDemande nouvelArticleDemande = articleDemande.clone();
                catalogueService.initPhotoSrc(nouvelArticleDemande.getArticleCatalogue());

                if (mapArticleCatalogueArticleDemande.get(articleDemande.getArticleCatalogue()) != null) {
                    ArticleDemande articleDemandeDejaPresentDansMap = mapArticleCatalogueArticleDemande
                            .get(articleDemande.getArticleCatalogue());
                    articleDemandeDejaPresentDansMap.setQuantite(
                            articleDemandeDejaPresentDansMap.getQuantite() + articleDemande.getQuantite());
                    articleDemandeDejaPresentDansMap
                            .setQuantiteCommande(articleDemandeDejaPresentDansMap.getQuantiteCommande()
                                    + articleDemande.getQuantiteCommande());

                } else {
                    mapArticleCatalogueArticleDemande.put(articleDemande.getArticleCatalogue(),
                            nouvelArticleDemande);
                }
            });
        }

        List<ArticleDemande> result = new ArrayList<>();
        for (ArticleCatalogue articleCatalogue : mapArticleCatalogueArticleDemande.keySet()) {
            result.add(mapArticleCatalogueArticleDemande.get(articleCatalogue));
        }

        Collections.sort(result, new ArticleDemandeComparator());
        return result;
    }

    private CommandeTreeNode construitSecondNiveauDemande(CommandeTreeNode root, Demande demande) {
        int nombreArticleValide = (int) demande.getListeArticleDemande().stream().filter(ArticleDemande::isValide)
                .count();
        return new CommandeTreeNode(root, demande.getNumeroCourt(), demande.getId(), demande.getPrixTotalCommande(),
                demande, nombreArticleValide, TypeCommandeNode.DEMANDE);
    }

    @Override
    public Map<Service, List<Demande>> construitMapServiceListeDemande(Commande commande) {
        Map<Service, List<Demande>> map = new HashMap<>();

        for (Demande demande : commande.getListeDemande()) {
            demande.getListeArticleDemande().stream().filter(ArticleDemande::isValide)
                    .forEach(articleDemande -> catalogueService.initPhotoSrc(articleDemande.getArticleCatalogue()));
            Service service = demande.getService();
            renseigneMapServiceListeDemande(map, demande, service);
        }
        return map;
    }

    private void renseigneMapServiceListeDemande(Map<Service, List<Demande>> map, Demande demande,
            Service service) {
        if (map.get(service) == null) {
            List<Demande> listeDemande = new ArrayList<>();
            listeDemande.add(demande);
            map.put(service, listeDemande);
        } else {
            map.get(service).add(demande);
        }
    }

    @Override
    public Map<AbstractEntity, Map<Service, List<ArticleDemande>>> construitMapFournisseurServiceListeArticleDemande(
            Commande commande) {
        Map<AbstractEntity, Map<Service, List<ArticleDemande>>> result = new HashMap<>();

        for (Demande demande : commande.getListeDemande()) {
            for (ArticleDemande articleDemande : demande.getListeArticleDemande()) {
                if (articleDemande.isRejete()) {
                    continue;
                }

                Service service = demande.getService();
                SousMarche sousMarche = articleDemande.getArticleCatalogue().getSousMarche();
                Fournisseur fournisseur = articleDemande.getArticleCatalogue().getFournisseur();

                if (sousMarche != null) {
                    renseigneMapFournisseurServiceListeArticleDemande(result, articleDemande, service, sousMarche);
                } else if (fournisseur != null) {
                    renseigneMapFournisseurServiceListeArticleDemande(result, articleDemande, service, fournisseur);
                } else {
                    renseigneMapFournisseurServiceListeArticleDemande(result, articleDemande, service,
                            new FakeEntity());
                }
            }
        }

        return result;
    }

    private void renseigneMapFournisseurServiceListeArticleDemande(
            Map<AbstractEntity, Map<Service, List<ArticleDemande>>> map, ArticleDemande articleDemande,
            Service service, AbstractEntity abstractEntity) {

        Map<Service, List<ArticleDemande>> mapServiceListeArticleDemande = map.get(abstractEntity);

        if (mapServiceListeArticleDemande != null && mapServiceListeArticleDemande.get(service) != null) {
            mapServiceListeArticleDemande.get(service).add(articleDemande);
        } else {
            if (mapServiceListeArticleDemande == null) {
                mapServiceListeArticleDemande = new HashMap<>();
            }

            List<ArticleDemande> listeArticleDemande = new ArrayList<>();
            listeArticleDemande.add(articleDemande);
            mapServiceListeArticleDemande.put(service, listeArticleDemande);
            map.put(abstractEntity, mapServiceListeArticleDemande);
        }
    }

    @Override
    public int countNombreCommandeEnAttenteReception() {
        return findAllEnAttenteReception().size();
    }

    @Override
    public Commande passeCommande(Commande commande) {
        AppUser appUser = authHelper.getCurrentUser();
        commande.setEtatCommande(EtatCommande.EN_ATTENTE_RECEPTION_COMMANDE);
        commande.setDatePassageCommande(LocalDateTime.now());
        commande.setPassageUser(appUser.getNomComplet());

        List<ArticleDemande> listeArticleDemandeQuantiteAgrege = construitListeArticleDemandeQuantiteAgrege(
                commande.getListeDemande());
        Map<Service, List<ArticleCommande>> mapServiceArticleCommande = new HashMap<>();
        for (ArticleDemande articleDemande : listeArticleDemandeQuantiteAgrege) {
            ArticleCommande articleCommande = new ArticleCommande();
            articleCommande.setArticleCatalogue(articleDemande.getArticleCatalogue());
            articleCommande.setQuantiteCommande(articleDemande.getQuantiteCommande());
            articleCommande.setQuantiteRecu(articleDemande.getQuantiteCommande());

            Service service = articleDemande.getDemande().getService();
            if (mapServiceArticleCommande.get(service) != null) {
                mapServiceArticleCommande.get(service).add(articleCommande);
            } else {
                List<ArticleCommande> listeArticleCommande = new ArrayList<>();
                listeArticleCommande.add(articleCommande);
                mapServiceArticleCommande.put(service, listeArticleCommande);
            }
        }

        for (Service service : mapServiceArticleCommande.keySet()) {
            CommandeService commandeService = new CommandeService();
            commandeService.setCommande(commande);
            commandeService.setService(service);
            List<ArticleCommande> listeArticleCommande = mapServiceArticleCommande.get(service);
            for (ArticleCommande articleCommande : listeArticleCommande) {
                articleCommande.setCommandeService(commandeService);
            }
            commandeService.setListeArticleCommande(listeArticleCommande);
            commande.getListeCommandeService().add(commandeService);
        }

        for (Demande demande : commande.getListeDemande()) {
            demande.setEtatDemande(EtatDemande.EN_ATTENTE_RECEPTION);
            demandeRepository.save(demande);
        }

        return commandeRepository.save(commande);
    }

    @Override
    public List<Commande> findAllByEtatCommandeOrderByDateCreationDesc(EtatCommande etatCommande) {
        List<Commande> listeCommande = commandeRepository
                .findAllByEtatCommandeOrderByDateCreationDesc(etatCommande);
        return initLazyListeCommande(listeCommande);
    }

    private List<Commande> initLazyListeCommande(List<Commande> listeCommande) {
        for (Commande commande : listeCommande) {
            AppockUtil.chargeCollection(commande.getListeCommandeService());
        }

        return listeCommande;
    }

    @Override
    public void valideCommande(Commande commande) {
        AppUser currentUser = authHelper.getCurrentUser();
        commande.setValidationUser(currentUser.getNomComplet());
        commande.setDateValidationCommande(LocalDateTime.now());
        commande.setEtatCommande(EtatCommande.RECEPTIONNE);
        commandeRepository.save(commande);
    }

    private void chargeListeDemandeOf(Commande commande) {
        for (Demande demande : commande.getListeDemande()) {
            AppockUtil.chargeCollection(demande.getListeArticleDemande());
            AppockUtil.chargeElement(demande.getService());
            AppockUtil.chargeElement(demande.getService().getDirection());
            AppockUtil.chargeElement(demande.getService().getDirection().getPole());
        }
    }
}