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

Java tutorial

Introduction

Here is the source code for nc.noumea.mairie.appock.services.impl.ImportExcelServiceImpl.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.utility.AppockUtil;
import nc.noumea.mairie.appock.entity.*;
import nc.noumea.mairie.appock.exception.ImportExcelException;
import nc.noumea.mairie.appock.repositories.*;
import nc.noumea.mairie.appock.services.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.zkoss.util.media.Media;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service("importExcelService")
@Scope(value = "singleton", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ImportExcelServiceImpl implements ImportExcelService {

    private static final int IMPORT_EXCEL_COLONNE_FAMILLE = 0;
    private static final int IMPORT_EXCEL_COLONNE_SOUS_FAMILLE = 1;
    private static final int IMPORT_EXCEL_COLONNE_REFERENCE = 2;
    private static final int IMPORT_EXCEL_COLONNE_DESIGNATION = 3;
    private static final int IMPORT_EXCEL_COLONNE_PRIX = 4;
    private static final int IMPORT_EXCEL_COLONNE_QUANTITE_COLISAGE = 5;
    private static final int IMPORT_EXCEL_COLONNE_TYPE_COLISAGE = 6;
    private static final int IMPORT_EXCEL_COLONNE_MARCHE = 7;
    private static final int IMPORT_EXCEL_COLONNE_SOUS_MARCHE = 8;
    private static final int IMPORT_EXCEL_COLONNE_FOURNISSEUR = 9;
    private static final int IMPORT_EXCEL_COLONNE_PHOTO = 10;
    private static final int IMPORT_EXCEL_COLONNE_LIEN_FOURNISSEUR = 11;

    @Autowired
    ArticleCatalogueService articleCatalogueService;

    @Autowired
    FamilleRepository familleRepository;

    @Autowired
    FamilleService familleService;

    @Autowired
    SousFamilleRepository sousFamilleRepository;

    @Autowired
    SousFamilleService sousFamilleService;

    @Autowired
    TypeColisageRepository typeColisageRepository;

    @Autowired
    MarcheRepository marcheRepository;

    @Autowired
    ArticleCatalogueRepository articleCatalogueRepository;

    @Autowired
    CatalogueService catalogueService;

    @Autowired
    FournisseurRepository fournisseurRepository;

    @Override
    public List<String> importCatalogue(Media media, Catalogue catalogue) throws IOException {
        List<String> messages = new ArrayList<>();
        XSSFWorkbook workbook = new XSSFWorkbook(media.getStreamData());
        XSSFSheet firstSheet = workbook.getSheetAt(0);

        int nbLigneTraite = 0;
        for (int ligne = 1; ligne < firstSheet.getPhysicalNumberOfRows(); ligne++) {
            try {
                traiterLigne(firstSheet, ligne, media, catalogue);
                nbLigneTraite++;
            } catch (ImportExcelException e) {
                messages.add(e.getMessage());
            }
        }

        if (!messages.isEmpty()) {
            messages.add(0, "Certaines rfrences n'ont pas pu tre importes : ");
        }

        StringBuilder statistiques = new StringBuilder("\nStatistiques :");
        statistiques.append("\n - Nombre de lignes total : " + (firstSheet.getPhysicalNumberOfRows() - 1));
        statistiques.append("\n - Nombre de rfrences importes : " + nbLigneTraite);
        statistiques.append("\n - Nombre de rfrences ignores : "
                + (firstSheet.getPhysicalNumberOfRows() - 1 - nbLigneTraite));
        messages.add(statistiques.toString());

        workbook.close();
        return messages;
    }

    private void traiterLigne(XSSFSheet sheet, int ligne, Media media, Catalogue catalogue)
            throws ImportExcelException, IOException {
        Row nextRow = sheet.getRow(ligne);

        String reference = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_REFERENCE));
        if (articleCatalogueService.findByReferenceAndCatalogue(reference, catalogue) != null) {
            throw new ImportExcelException(ligne + 1, reference, "L'article existe dj dans ce catalogue");
        }

        Famille famille = gereImportFamille(catalogue, nextRow);
        SousMarche sousMarcheCatalogue = gereImportSousMarche(nextRow);

        String designation = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_DESIGNATION));
        String prix = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_PRIX));
        String quantiteColisage = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_QUANTITE_COLISAGE));
        String lienFournisseur = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_LIEN_FOURNISSEUR));

        ArticleCatalogue articleCatalogue = new ArticleCatalogue();
        articleCatalogue.setLibelle(designation);
        articleCatalogue.setSousMarche(sousMarcheCatalogue);
        articleCatalogue.setSousFamille(gereImportSousFamille(catalogue, nextRow, famille));
        articleCatalogue.setReference(reference);
        articleCatalogue.setPrix(prix != null ? Integer.parseInt(prix) : null);
        articleCatalogue.setQuantiteColisage(quantiteColisage != null ? Integer.parseInt(quantiteColisage) : null);
        articleCatalogue.setTypeColisage(gereImportTypeColisage(nextRow));
        articleCatalogue.setLienFournisseur(lienFournisseur);
        articleCatalogue.setFournisseur(gereImportFournisseur(nextRow, sousMarcheCatalogue));
        articleCatalogue
                .setPhotoArticleCatalogue(recuperePhotoArticleCatalogue(sheet, media.getName(), ligne, reference));

        articleCatalogueRepository.save(articleCatalogue);
    }

    private Fournisseur gereImportFournisseur(Row nextRow, SousMarche sousMarcheCatalogue) {
        Fournisseur fournisseur = null;
        String nomFournisseur = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_FOURNISSEUR));
        if (StringUtils.isNotBlank(nomFournisseur) && sousMarcheCatalogue == null) {
            fournisseur = fournisseurRepository.findFirstByNom(nomFournisseur);
            if (fournisseur == null) {
                fournisseur = new Fournisseur();
                fournisseur.setNom(nomFournisseur);
                fournisseur = fournisseurRepository.save(fournisseur);
            }
        }
        return fournisseur;
    }

    private SousMarche gereImportSousMarche(Row nextRow) {
        SousMarche sousMarcheCatalogue = null;
        String libelleMarche = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_MARCHE));
        Marche marche = marcheRepository.findFirstByLibelle(libelleMarche);
        if (marche != null) {
            String libelleCourtSousMarche = getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_SOUS_MARCHE));
            for (SousMarche sousMarche : marche.getListeSousMarche()) {
                if (sousMarche.getLibelleCourt().equals(libelleCourtSousMarche)) {
                    sousMarcheCatalogue = sousMarche;
                    break;
                }
            }
        }
        return sousMarcheCatalogue;
    }

    private TypeColisage gereImportTypeColisage(Row nextRow) {
        String libelleTypeColisage = AppockUtil
                .majusculeSansAccentTrim(getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_TYPE_COLISAGE)));
        TypeColisage typeColisage = typeColisageRepository.findFirstByLibelle(libelleTypeColisage);
        if (typeColisage == null) {
            typeColisage = new TypeColisage();
            typeColisage.setLibelle(libelleTypeColisage);
            typeColisage = typeColisageRepository.save(typeColisage);
        }
        return typeColisage;
    }

    private SousFamille gereImportSousFamille(Catalogue catalogue, Row nextRow, Famille famille) {
        String libelleSousFamille = AppockUtil
                .majusculeSansAccentTrim(getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_SOUS_FAMILLE)));
        SousFamille sousFamille = sousFamilleService.findByLibelleAndCatalogue(libelleSousFamille, catalogue);
        if (sousFamille == null) {
            sousFamille = new SousFamille();
            sousFamille.setLibelle(libelleSousFamille);
            sousFamille.setFamille(famille);
            sousFamille = sousFamilleRepository.save(sousFamille);
        }
        return sousFamille;
    }

    private Famille gereImportFamille(Catalogue catalogue, Row nextRow) {
        String libelleFamille = AppockUtil
                .majusculeSansAccentTrim(getCellValue(nextRow.getCell(IMPORT_EXCEL_COLONNE_FAMILLE)));
        Famille famille = familleService.findByLibelleAndCatalogue(libelleFamille, catalogue);
        if (famille == null) {
            famille = new Famille();
            famille.setLibelle(libelleFamille);
            famille.setCatalogue(catalogue);
            famille = familleRepository.save(famille);
        }
        return famille;
    }

    private String getCellValue(Cell cell) {
        if (cell == null) {
            return null;
        }

        // Les deprecated son un bug connu de la librairie, ils se sont plants et l'ont laiss deperecated
        if (cell.getCellTypeEnum() == CellType.STRING) {
            return cell.getStringCellValue();
        } else if (cell.getCellTypeEnum() == CellType.NUMERIC) {
            return String.valueOf((int) cell.getNumericCellValue());
        }

        return null;
    }

    private PhotoArticleCatalogue recuperePhotoArticleCatalogue(XSSFSheet firstSheet, String nomFichier, int numRow,
            String reference) throws IOException, ImportExcelException {

        Stream<XSSFShape> shapeStream = firstSheet.getDrawingPatriarch().getShapes().stream() //
                .filter(shape -> {
                    if (!(shape instanceof XSSFPicture)) {
                        return false;
                    }
                    XSSFPicture picture = (XSSFPicture) shape;
                    XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();
                    XSSFRow pictureRow = firstSheet.getRow(anchor.getRow1());
                    return (anchor.getCol1() == IMPORT_EXCEL_COLONNE_PHOTO && pictureRow != null
                            && pictureRow.getRowNum() == numRow);
                });

        List<XSSFShape> listeShape = shapeStream.collect(Collectors.toList());
        if (listeShape.isEmpty()) {
            throw new ImportExcelException(numRow + 1, reference, "Aucune image n'a t trouve");
        } else if (listeShape.size() > 1) {
            throw new ImportExcelException(numRow + 1, reference, "Plusieurs images ont t trouves");
        }

        XSSFPicture picture = (XSSFPicture) listeShape.get(0);
        byte[] content = picture.getPictureData().getData();
        content = AppockUtil.scale(content, 80, 80);

        if (content == null) {
            throw new ImportExcelException(numRow + 1, reference, "Aucune image n'a t trouve");
        }

        return catalogueService.savePhotoArticleCatalogue(content, nomFichier);
    }

}