OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 174 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
 * 
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each file.
 */
 
 package org.openconcerto.erp.model;

import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.PreviewFrame;
import org.openconcerto.erp.core.customerrelationship.mail.EmailTemplate;
import org.openconcerto.erp.core.customerrelationship.mail.ValueListener;
import org.openconcerto.erp.generationDoc.AbstractSheetXml;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel.EditMode;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.sql.view.list.action.ListEvent;
import org.openconcerto.ui.EmailComposer;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.Action;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.ListMap;
import org.openconcerto.utils.i18n.Grammar;
import org.openconcerto.utils.i18n.TranslationManager;

import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;

import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class MouseSheetXmlListeListener {

    private Class<? extends AbstractSheetXml> clazz;
    protected IListe liste;

    private boolean previewIsVisible = true;
    private boolean showIsVisible = true;
    private boolean printIsVisible = true;
    private boolean generateIsVisible = true;
    private boolean previewHeader = false;
    private boolean showHeader = false;
    private boolean generateHeader = false;
    private SQLElement element;

    public MouseSheetXmlListeListener(SQLElement element, Class<? extends AbstractSheetXml> clazz) {
        this(element, clazz, true, true, true, true);

    }

    public MouseSheetXmlListeListener(SQLElement element, Class<? extends AbstractSheetXml> clazz, boolean show, boolean preview, boolean print, boolean generate) {
        this.element = element;
        this.clazz = clazz;
        this.printIsVisible = print;
        this.previewIsVisible = preview;
        this.showIsVisible = show;
        this.generateIsVisible = generate;
    }

    protected Class<? extends AbstractSheetXml> getSheetClass() {
        return this.clazz;
    }

    protected AbstractSheetXml createAbstractSheet(SQLRow row) {
        try {
            Constructor<? extends AbstractSheetXml> ctor = getSheetClass().getConstructor(SQLRow.class);
            AbstractSheetXml sheet = ctor.newInstance(row);
            return sheet;
        } catch (Exception e) {
            ExceptionHandler.handle("sheet creation error", e);
        }
        return null;
    }

    public List<AbstractSheetXml> createAbstractSheets(List<SQLRow> rows) {
        final List<AbstractSheetXml> sheets = new ArrayList<>(rows.size());
        try {
            final Constructor<? extends AbstractSheetXml> ctor = getSheetClass().getConstructor(SQLRow.class);
            for (SQLRow row : rows) {
                AbstractSheetXml sheet = ctor.newInstance(row);
                sheets.add(sheet);
            }
        } catch (Exception e) {
            ExceptionHandler.handle("sheet creation error", e);
        }
        return sheets;
    }

    protected String getMailObject(SQLRow row) {
        return "";
    }

    public void setPreviewHeader(boolean previewHeader) {
        this.previewHeader = previewHeader;
    }

    public void setGenerateHeader(boolean generateHeader) {
        this.generateHeader = generateHeader;
    }

    public void setShowHeader(boolean showHeader) {
        this.showHeader = showHeader;
    }

    public void sendMail(EmailTemplate template, final AbstractSheetXml sheet, final boolean readOnly) {
        List<AbstractSheetXml> l = new ArrayList<>(1);
        l.add(sheet);
        sendMail(template, l, readOnly);
    }

    protected void sendMail(EmailTemplate template, final List<AbstractSheetXml> sheets, final boolean readOnly) {
        final Thread t = new Thread() {
            @Override
            public void run() {
                ListMap<String, File> mailFilesMap = new ListMap<>();
                for (AbstractSheetXml sheet : sheets) {
                    String mail = "";
                    final SQLRow row = sheet.getSQLRow();
                    Set<SQLField> setContact = null;
                    SQLTable tableContact = Configuration.getInstance().getRoot().findTable("CONTACT");
                    setContact = row.getTable().getForeignKeys(tableContact);

                    Set<SQLField> setClient = null;
                    SQLTable tableClient = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("CLIENT");
                    setClient = row.getTable().getForeignKeys(tableClient);

                    for (SQLField field : setContact) {
                        if (mail == null || mail.trim().length() == 0) {
                            mail = row.getForeignRow(field.getName()).getString("EMAIL");
                        }
                    }
                    String nomClient = "";
                    if (setClient != null && (mail == null || mail.trim().length() == 0)) {
                            for (SQLField field : setClient) {
                                SQLRow rowCli = row.getForeignRow(field.getName());
                                if (mail == null || mail.trim().length() == 0) {
                                    mail = rowCli.getString("MAIL");
                                }
                                nomClient = rowCli.getString("NOM");
                            }
                    }

                    if (mail.trim().length() == 0) {
                        mail = nomClient;
                    }

                    String table = row.getTable().getName();
                    if (table.equalsIgnoreCase("COMMANDE") || table.equalsIgnoreCase("DEMANDE_PRIX") || table.equalsIgnoreCase("FACTURE_FOURNISSEUR")) {
                        mail = "";
                    }
                    if (mail == null || mail.trim().length() == 0) {
                        SQLTable tableF = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("FOURNISSEUR");
                        Set<SQLField> setF = null;
                        setF = row.getTable().getForeignKeys(tableF);

                        if (setF != null) {

                            for (SQLField field : setF) {
                                SQLRow rowF = row.getForeignRow(field.getName());
                                if (mail == null || mail.trim().length() == 0) {
                                    mail = rowF.getString("MAIL");
                                }
                            }
                        }

                        if (mail == null || mail.trim().length() == 0) {
                            SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
                            if (base.containsTable("MONTEUR")) {
                                SQLTable tableM = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("MONTEUR");
                                Set<SQLField> setM = null;
                                setM = row.getTable().getForeignKeys(tableM);
                                if (setM != null) {
                                    for (SQLField field : setM) {
                                        SQLRow rowM = row.getForeignRow(field.getName());
                                        if (rowM.getForeignRow("ID_CONTACT_FOURNISSEUR") != null && !rowM.getForeignRow("ID_CONTACT_FOURNISSEUR").isUndefined()) {
                                            mail = rowM.getForeignRow("ID_CONTACT_FOURNISSEUR").getString("EMAIL");
                                        }
                                    }
                                }
                            }
                        }
                        if (mail == null || mail.trim().length() == 0) {
                            SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
                            if (base.containsTable("TRANSPORTEUR")) {

                                SQLTable tableM = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getTable("TRANSPORTEUR");
                                Set<SQLField> setM = null;
                                setM = row.getTable().getForeignKeys(tableM);

                                if (setM != null) {

                                    for (SQLField field : setM) {
                                        SQLRow rowM = row.getForeignRow(field.getName());
                                        if (rowM.getForeignRow("ID_CONTACT_FOURNISSEUR") != null && !rowM.getForeignRow("ID_CONTACT_FOURNISSEUR").isUndefined()) {
                                            mail = rowM.getForeignRow("ID_CONTACT_FOURNISSEUR").getString("EMAIL");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    try {
                        if (readOnly) {
                            mailFilesMap.add(mail, sheet.getOrCreatePDFDocumentFile(true).getAbsoluteFile());
                        } else {
                            mailFilesMap.add(mail, sheet.getOrCreateDocumentFile().getAbsoluteFile());

                        }
                    } catch (Exception e) {
                        ExceptionHandler.handle("Impossible de charger le document PDF", e);
                    }
                }

                for (final String mailDest : mailFilesMap.keySet()) {

                    final List<File> files = mailFilesMap.get(mailDest);

                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                String subject = sheets.get(0).getReference();
                                if (template != null) {
                                    subject = template.getTitle() + " " + sheets.get(0).getReference().trim();
                                }
                                subject = subject.trim();
                                if (subject.isEmpty()) {
                                    final StringJoiner joiner = new StringJoiner(", ");
                                    for (File f : files) {
                                        joiner.add(f.getName());
                                    }
                                    subject = joiner.toString();
                                }
                                String message = getMailObject(sheets.get(0).getSQLRow());
                                if (template != null) {
                                    if (template.getText().contains("{message}")) {
                                        message = template.getText().replace("{message}", message);
                                    } else {
                                        message += template.getText();
                                    }
                                }
                                EmailComposer.getInstance().compose(mailDest, subject, message, files.toArray(new File[files.size()]));
                            } catch (Exception e) {
                                ExceptionHandler.handle("Impossible d'envoyer le courriel!", e);
                            }
                        }
                    });
                }

            }

        };
        t.start();

    }

    public List<RowAction> addToMenu() {
        return null;
    }

    public List<RowAction> getRowActions() {
        List<RowAction> l = new ArrayList<>();

        if (!Boolean.getBoolean("org.openconcerto.oo.useODSViewer")) {
            if (this.showIsVisible) {
                RowAction action = new RowAction(new AbstractAction() {
                    public void actionPerformed(ActionEvent ev) {
                        try {
                            createAbstractSheet(IListe.get(ev).fetchSelectedRow()).openDocument(false);
                        } catch (Exception e) {
                            ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
                        }
                    }

                }, this.previewHeader, "document.modify") {

                    @Override
                    public boolean enabledFor(ListEvent evt) {
                        // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
                        // du temps
                        return evt.getSelectedRow() != null && (evt.getTotalRowCount() >= 1);
                    }

                };
                l.add(action);

            }
        } else {
            // ODS Viewer
            if (this.previewIsVisible) {
                l.add(new RowAction(new AbstractAction() {
                    public void actionPerformed(ActionEvent ev) {
                        try {
                            final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).fetchSelectedRow());
                            final SQLTable table = IListe.get(ev).getSource().getPrimaryTable();
                            final Action emailAction = new Action(TranslationManager.getInstance().getTranslationForAction("document.pdf.send.email")) {

                                @Override
                                public void run(Object source) {
                                    EmailTemplate.askTemplate(IListe.get(ev), table.getDBRoot(), new ValueListener() {

                                        @Override
                                        public void valueSelected(Object value) {
                                            sendMail((EmailTemplate) value, sheet, true);
                                        }
                                    });

                                }
                            };
                            final Action modifyAction = new Action(
                                    TranslationManager.getInstance().getTranslationForAction("modify") + " " + element.getName().getVariant(Grammar.DEFINITE_ARTICLE_SINGULAR)) {

                                @Override
                                public void run(Object source) {
                                    if (source instanceof PreviewFrame) {
                                        ((PreviewFrame) source).dispose();
                                    }
                                    final SQLComponent component = element.createDefaultComponent();
                                    final EditFrame f = new EditFrame(component, EditMode.MODIFICATION);
                                    f.selectionId(IListe.get(ev).getSelectedId());
                                    FrameUtil.show(f);

                                }
                            };
                            sheet.showPreviewDocument(Arrays.asList(emailAction, modifyAction));
                        } catch (Exception e) {
                            ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
                        }
                    }

                }, this.previewHeader, "document.preview") {

                    @Override
                    public boolean enabledFor(ListEvent evt) {
                        // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
                        // du temps
                        return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
                    }
                });

            }
        }

        // action supplémentaire
        List<RowAction> list = addToMenu();
        if (list != null) {
            for (RowAction rowAction : list) {
                l.add(rowAction);
            }
        }

        if (Boolean.getBoolean("org.openconcerto.oo.useODSViewer") && this.showIsVisible) {
            l.add(new RowAction(new AbstractAction() {
                public void actionPerformed(ActionEvent ev) {
                    try {
                        createAbstractSheet(IListe.get(ev).fetchSelectedRow()).openDocument(false);
                    } catch (Exception e) {
                        ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
                    }
                }
            }, this.showHeader, "document.modify") {

                @Override
                public boolean enabledFor(ListEvent evt) {
                    // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
                    // du temps
                    return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
                }
            });

        }

        l.add(new RowAction(new AbstractAction() {
            public void actionPerformed(ActionEvent ev) {
                try {
                    File file = createAbstractSheet(IListe.get(ev).fetchSelectedRow()).getOrCreatePDFDocumentFile(true);

                    JFileChooser fileChooser = new JFileChooser();
                    fileChooser.setSelectedFile(file);
                    fileChooser.setDialogTitle(TranslationManager.getInstance().getTranslationForAction("document.saveToPDF"));

                    int userSelection = fileChooser.showSaveDialog(IListe.get(ev));

                    if (userSelection == JFileChooser.APPROVE_OPTION) {
                        File fileToSave = fileChooser.getSelectedFile();
                        InputStream is = null;
                        OutputStream os = null;
                        try {
                            is = new FileInputStream(file);
                            os = new FileOutputStream(fileToSave);
                            byte[] buffer = new byte[4096];
                            int length;
                            while ((length = is.read(buffer)) > 0) {
                                os.write(buffer, 0, length);
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        } finally {

                            try {
                                if (is != null)
                                    is.close();
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                            try {
                                if (os != null)
                                    os.close();
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                        }
                    }

                } catch (Exception e) {
                    ExceptionHandler.handle("Impossible d'ouvrir le fichier", e);
                }
            }
        }, false, "document.saveToPDF") {

            @Override
            public boolean enabledFor(ListEvent evt) {
                // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre
                // du temps
                return evt.getSelectedRow() != null && evt.getSelectedRowAccessors().size() == 1;
            }
        });

        if (this.printIsVisible) {

            // Impression rapide : imprime le ou les documents sélectionnés (les génère si besoin)
            // en proposant l'interface Java d'impression
            l.add(new RowAction(new PrintDocumentAction(this), false, "document.print") {

                @Override
                public boolean enabledFor(ListEvent evt) {
                    return evt.getSelectedRow() != null && evt.getTotalRowCount() > 0;
                }
            });

        }

        if (this.showIsVisible)

        {

            l.add(getSendMailPDF());

            l.add(getSendMail());

        }
        if (this.generateIsVisible) {
            l.add(new RowAction(new AbstractAction() {
                public void actionPerformed(ActionEvent ev) {

                    List<SQLRowAccessor> l = IListe.get(ev).getSelectedRowAccessors();

                    if (l.size() == 1) {
                        createDocument(ev);
                    } else {
                        createDocuments(l);
                    }
                }
            }, this.generateHeader, "document.create") {

                @Override
                public boolean enabledFor(ListEvent selection) {
                    return selection != null && selection.getTotalRowCount() > 0;
                }

            });
        }

        return l;
    }

    public RowAction getSendMail() {
        return new RowAction(new AbstractAction() {
            public void actionPerformed(ActionEvent ev) {
                sendMail(ev, false);
            }
        }, false, "document.send.email") {

            @Override
            public boolean enabledFor(ListEvent evt) {
                // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre du
                // temps
                return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
            }

        };
    }

    public RowAction getSendMailPDF() {
        return new RowAction(new AbstractAction() {
            public void actionPerformed(ActionEvent ev) {
                sendMail(ev, true);
            }
        }, false, "document.pdf.send.email") {

            @Override
            public boolean enabledFor(ListEvent evt) {
                // On ne teste pas l'existence du fichier génété car les IOs peuvent prendre du
                // temps
                return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1;
            }

        };

    }

    private void createDocuments(List<? extends SQLRowAccessor> selection) {
        int a = JOptionPane.showConfirmDialog(null, "Voulez vous recréer l'ensemble des documents sélectionnés?", "Génération de documents", JOptionPane.YES_NO_OPTION);
        if (a == JOptionPane.YES_OPTION) {
            for (SQLRowAccessor sqlRowAccessor : selection) {
                final AbstractSheetXml sheet = createAbstractSheet(sqlRowAccessor.getTable().getRow(sqlRowAccessor.getID()));
                sheet.createDocumentAsynchronous();
                sheet.showPrintAndExportAsynchronous(false, false, true, Collections.emptyList());
            }
        }
    }

    private void createDocument(ActionEvent ev) {
        final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).fetchSelectedRow());
        if (sheet.getGeneratedFile().exists()) {
            int a = JOptionPane.showConfirmDialog(null, "Voulez vous remplacer le document existant?", "Génération de documents", JOptionPane.YES_NO_OPTION);
            if (a == JOptionPane.YES_OPTION) {
                sheet.createDocumentAsynchronous();
                sheet.showPrintAndExportAsynchronous(true, false, true, Collections.emptyList());
                return;
            }
        }

        try {
            sheet.getOrCreateDocumentFile();
            sheet.showPrintAndExportAsynchronous(true, false, false, Collections.emptyList());
        } catch (Exception exn) {
            exn.printStackTrace();
        }

    }

    /**
     * Action sur le double clic
     * 
     * @return
     */
    public RowAction getDefaultRowAction() {
        return new RowAction(new AbstractAction() {
            public void actionPerformed(ActionEvent ev) {
                final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).fetchSelectedRow().asRow());
                try {
                    sheet.getOrCreateDocumentFile();
                    sheet.showPrintAndExportAsynchronous(true, false, true, Collections.emptyList());
                } catch (Exception exn) {
                    ExceptionHandler.handle("Une erreur est survenue lors de la création du document.", exn);
                }
            }
        }, false, false, "document.create") {

            @Override
            public boolean enabledFor(ListEvent selection) {
                return selection != null && selection.getTotalRowCount() == 1;
            }

            @Override
            public javax.swing.Action getDefaultAction(final ListEvent evt) {
                return this.getAction();
            }
        };
    }

    protected void sendMail(ActionEvent ev, boolean pdf) {
        final List<SQLRowAccessor> selectedRows = IListe.get(ev).getSelectedRowAccessors();

        final SQLTable table = IListe.get(ev).getSource().getPrimaryTable();
        final List<SQLRow> rows = new ArrayList<>();
        for (SQLRowAccessor r : selectedRows) {
            rows.add(table.getRow(r.getID()));
        }

        EmailTemplate.askTemplate(IListe.get(ev), table.getDBRoot(), new ValueListener() {

            @Override
            public void valueSelected(Object value) {
                sendMail((EmailTemplate) value, createAbstractSheets(rows), pdf);
            }
        });
    }
}