OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 177 | Rev 182 | 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 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.core.supplychain.order.component;

import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.component.TransfertBaseSQLComponent;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.element.NumerotationAutoSQLElement;
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.common.ui.TotalPanel;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.finance.accounting.model.CurrencyConverter;
import org.openconcerto.erp.core.finance.payment.component.ModeDeReglementSQLComponent;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.supplychain.order.ui.FactureFournisseurItemTable;
import org.openconcerto.erp.generationDoc.gestcomm.FactureFournisseurXmlSheet;
import org.openconcerto.erp.generationEcritures.GenerationMvtFactureFournisseur;
import org.openconcerto.erp.panel.PanelOOSQLComponent;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.ElementSQLObject;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLBackgroundTableCache;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.preferences.SQLPreferences;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLRequestComboBox;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.ui.AutoHideListener;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.component.ITextArea;
import org.openconcerto.ui.preferences.DefaultProps;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.checks.ValidState;
import org.openconcerto.utils.text.SimpleDocumentListener;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

public class FactureFournisseurSQLComponent extends TransfertBaseSQLComponent {

    private FactureFournisseurItemTable table = new FactureFournisseurItemTable();
    private final ITextArea infos = new ITextArea(3, 3);
    private ElementComboBox fourn = new ElementComboBox();
    private ElementComboBox comptePCE = new ElementComboBox();
    private ElementComboBox avoirFourn = new ElementComboBox();
    private ElementComboBox avoirFourn2 = new ElementComboBox();

    private PanelOOSQLComponent panelOO;
    final JPanel panelAdrSpec = new JPanel(new GridBagLayout());
    private JDate dateCommande = new JDate();
    private final JTextField fieldTaux = new JTextField(15);
    private final DeviseField textNetAPayer = new DeviseField(15);
    private final JLabel labelTaux = new JLabel();
    private ElementSQLObject eltModeRegl;
    DeviseField fieldTTC = new DeviseField();
    DeviseField avoirTTC = new DeviseField();
    private PropertyChangeListener listenerModeReglDefaut = new PropertyChangeListener() {

        public void propertyChange(PropertyChangeEvent evt) {

            final SQLRow rowFourn = FactureFournisseurSQLComponent.this.fourn.getRequest().getPrimaryTable().getRow(FactureFournisseurSQLComponent.this.fourn.getWantedID());
            if ((getMode() == Mode.INSERTION || !isFilling()) && rowFourn != null && !rowFourn.isUndefined()) {

                int idModeRegl = rowFourn.getInt("ID_MODE_REGLEMENT");
                if (idModeRegl > 1 && FactureFournisseurSQLComponent.this.eltModeRegl != null && getMode() == Mode.INSERTION) {
                    SQLElement sqlEltModeRegl = getElement().getDirectory().getElement("MODE_REGLEMENT");
                    SQLRow rowModeRegl = sqlEltModeRegl.getTable().getRow(idModeRegl);
                    SQLRowValues rowVals = rowModeRegl.createUpdateRow();
                    rowVals.clearPrimaryKeys();
                    FactureFournisseurSQLComponent.this.eltModeRegl.setValue(rowVals);
                }

            }

        }

    };

    public FactureFournisseurSQLComponent() {
        super(Configuration.getInstance().getDirectory().getElement("FACTURE_FOURNISSEUR"));
    }

    public ElementComboBox getBoxFournisseur() {
        return this.fourn;
    }

    @Override
    protected Set<String> createRequiredNames() {
        final Set<String> s = new HashSet<>(1);
        if (getTable().contains("ID_TYPE_CMD")) {
            s.add("ID_TYPE_CMD");
        }
        return s;
    }

    @Override
    public synchronized ValidState getValidState() {
        if (getTable().contains("ID_COMPTE_PCE") && getTable().contains("ID_TYPE_CMD") && getTable().getTable("FACTURE_FOURNISSEUR_ELEMENT").contains("ID_COMPTE_PCE")) {
            SQLRequestComboBox boxCpt = (SQLRequestComboBox) getView("ID_COMPTE_PCE").getComp();
            final SQLRow selectedCpt = boxCpt.getSelectedRow();
            if (selectedCpt == null || selectedCpt.isUndefined()) {
                RowValuesTableModel tableRow = this.table.getRowValuesTable().getRowValuesTableModel();

                for (int i = 0; i < tableRow.getRowCount(); i++) {
                    SQLRowValues rowVals = tableRow.getRowValuesAt(i);
                    if (rowVals.getInt("QTE") != 0 && (rowVals.getObject("ID_COMPTE_PCE") == null || rowVals.isForeignEmpty("ID_COMPTE_PCE"))) {
                        return ValidState.create(false, "Aucun compte global sélectionné et une ligne avec une quantité > 0 n'est pas affectée à un compte!");
                    }
                }
            }

        }
        return super.getValidState();
    }

    private JUniqueTextField numero;

    public void addViews() {
        this.setLayout(new GridBagLayout());
        final GridBagConstraints c = new DefaultGridBagConstraints();

        if (getTable().getTable("NUMEROTATION_AUTO").contains("FACTURE_FOURNISSEUR_START")) {
            this.numero = new JUniqueTextField(35) {
                @Override
                public String getAutoRefreshNumber() {
                    if (getMode() == Mode.INSERTION) {
                        final Date date = FactureFournisseurSQLComponent.this.dateCommande.getDate();
                        return NumerotationAutoSQLElement.getNextNumero(getElement().getClass(), date == null ? new Date() : date);
                    } else {
                        return null;
                    }
                }
            };
            this.dateCommande.addValueListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (!isFilling() && FactureFournisseurSQLComponent.this.dateCommande.getValue() != null) {

                        final String nextNumero = NumerotationAutoSQLElement.getNextNumero(getElement().getClass(), FactureFournisseurSQLComponent.this.dateCommande.getValue());

                        if (FactureFournisseurSQLComponent.this.numero.getText().trim().length() > 0 && !nextNumero.equalsIgnoreCase(FactureFournisseurSQLComponent.this.numero.getText())) {

                            int answer = JOptionPane.showConfirmDialog(FactureFournisseurSQLComponent.this, "Voulez vous actualiser le numéro de la facture?", "Changement du numéro de facture",
                                    JOptionPane.YES_NO_OPTION);
                            if (answer == JOptionPane.NO_OPTION) {
                                return;
                            }
                        }

                        FactureFournisseurSQLComponent.this.numero.setText(nextNumero);

                    }
                }
            });
        } else {
            this.numero = new JUniqueTextField(35);
        }
        // Numero du commande
        c.gridx = 0;
        c.weightx = 0;
        this.add(new JLabel(getLabelFor("NUMERO"), SwingConstants.RIGHT), c);

        c.gridx++;
        c.weightx = 1;
        c.fill = GridBagConstraints.NONE;
        DefaultGridBagConstraints.lockMinimumSize(this.numero);
        this.add(this.numero, c);

        // Date
        JLabel labelDate = new JLabel(getLabelFor("DATE"));
        labelDate.setHorizontalAlignment(SwingConstants.RIGHT);
        c.gridx = 2;
        c.weightx = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        this.add(labelDate, c);

        c.gridx++;
        c.fill = GridBagConstraints.NONE;
        this.add(this.dateCommande, c);

        this.dateCommande.addValueListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (!isFilling() && FactureFournisseurSQLComponent.this.dateCommande.getValue() != null) {
                    FactureFournisseurSQLComponent.this.table.setDateDevise(FactureFournisseurSQLComponent.this.dateCommande.getValue());
                    updateLabelTauxConversion();
                }
            }
        });

        // Fournisseur
        c.gridx = 0;
        c.gridy++;
        c.weightx = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        this.add(new JLabel(getLabelFor("ID_FOURNISSEUR"), SwingConstants.RIGHT), c);

        c.gridx = GridBagConstraints.RELATIVE;
        c.gridwidth = 1;
        c.weightx = 1;
        c.weighty = 0;
        c.fill = GridBagConstraints.NONE;
        this.add(this.fourn, c);
        addRequiredSQLObject(this.fourn, "ID_FOURNISSEUR");

        this.fourn.addModelListener("wantedID", new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                int wantedID = FactureFournisseurSQLComponent.this.fourn.getWantedID();
                if (wantedID != SQLRow.NONEXISTANT_ID && wantedID >= SQLRow.MIN_VALID_ID) {

                    final SQLRow rowF = getTable().getForeignTable("ID_FOURNISSEUR").getRow(wantedID);

                    if (rowF.getObject("ID_CATEGORIE_COMPTABLE") != null && !rowF.isForeignEmpty("ID_CATEGORIE_COMPTABLE")) {
                        FactureFournisseurSQLComponent.this.table.setRowCatComptable(rowF.getForeign("ID_CATEGORIE_COMPTABLE"));
                    } else {
                        FactureFournisseurSQLComponent.this.table.setRowCatComptable(null);
                    }

                } else {
                    FactureFournisseurSQLComponent.this.table.setRowCatComptable(null);
                }
            }
        });
        this.fourn.addModelListener("wantedID", this.listenerModeReglDefaut);

        // Champ Module
        c.gridx = 0;
        c.gridy++;
        c.gridwidth = GridBagConstraints.REMAINDER;
        final JPanel addP = ComptaSQLConfElement.createAdditionalPanel();
        this.setAdditionalFieldsPanel(new FormLayouter(addP, 2));
        this.add(addP, c);

        c.gridy++;
        c.gridwidth = 1;

        SQLPreferences prefs = SQLPreferences.getMemCached(getTable().getDBRoot());
        final boolean showDevise = prefs.getBoolean(AbstractVenteArticleItemTable.ARTICLE_SHOW_DEVISE, false);

        final ElementComboBox boxDevise = new ElementComboBox();
        if (showDevise) {
            // Devise
            c.gridx = 0;
            c.gridy++;
            c.weightx = 0;
            c.fill = GridBagConstraints.HORIZONTAL;
            this.add(new JLabel(getLabelFor("ID_DEVISE"), SwingConstants.RIGHT), c);

            c.gridx++;
            c.gridwidth = 1;
            c.weightx = 1;
            c.weighty = 0;
            c.fill = GridBagConstraints.NONE;
            this.add(boxDevise, c);
            this.addView(boxDevise, "ID_DEVISE");

            this.fourn.addModelListener("wantedID", new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    FactureFournisseurSQLComponent.this.table.setFournisseur(FactureFournisseurSQLComponent.this.fourn.getSelectedRow());
                    SQLRow row = FactureFournisseurSQLComponent.this.fourn.getSelectedRow();
                    if (!isFilling()) {
                        if (row != null && !row.isUndefined() && !row.isForeignEmpty("ID_DEVISE")) {
                            boxDevise.setValue(row.getForeignID("ID_DEVISE"));
                        }
                    }

                    if (row != null && !row.isUndefined()) {
                        FactureFournisseurSQLComponent.this.avoirFourn.getRequest()
                                .setWhere(new Where(FactureFournisseurSQLComponent.this.avoirFourn.getRequest().getPrimaryTable().getField("ID_FOURNISSEUR"), "=", row.getID()));
                    } else {
                        FactureFournisseurSQLComponent.this.avoirFourn.getRequest().setWhere(null);
                    }
                }
            });

            if (getTable().contains("TAUX_APPLIQUE")) {
                // Devise
                c.gridx++;
                c.weightx = 0;
                c.fill = GridBagConstraints.HORIZONTAL;
                this.add(new JLabel(getLabelFor("TAUX_APPLIQUE"), SwingConstants.RIGHT), c);

                c.gridx++;
                c.gridwidth = 1;
                c.weightx = 1;
                c.weighty = 0;
                c.fill = GridBagConstraints.NONE;

                DefaultGridBagConstraints.lockMinimumSize(this.fieldTaux);
                JPanel panelTaux = new JPanel();
                panelTaux.add(this.fieldTaux);
                panelTaux.add(this.labelTaux);
                this.add(panelTaux, c);
                this.addView(this.fieldTaux, "TAUX_APPLIQUE");

            }
        }

        // Compte pce
        c.gridx = 0;
        c.gridy++;
        c.weightx = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        this.add(new JLabel(getLabelFor("ID_COMPTE_PCE"), SwingConstants.RIGHT), c);

        c.gridx = GridBagConstraints.RELATIVE;
        c.gridwidth = 1;
        c.weightx = 1;
        c.weighty = 0;
        c.fill = GridBagConstraints.NONE;

        this.add(this.comptePCE, c);

        final SQLElement foreignElement = getElement().getForeignElement("ID_COMPTE_PCE");
        final ComboSQLRequest comboRequest = foreignElement.getComboRequest(true);
        comboRequest.setWhere(new Where(foreignElement.getTable().getField("NUMERO"), "LIKE", "6%"));
        this.comptePCE.init(foreignElement, comboRequest);
        this.addView(this.comptePCE, "ID_COMPTE_PCE");

        // Reference
        c.gridx = 0;
        c.gridy++;
        c.gridwidth = 1;
        c.weightx = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.EAST;
        this.add(new JLabel(getLabelFor("NOM"), SwingConstants.RIGHT), c);

        final JTextField textNom = new JTextField();
        c.gridx++;
        c.weightx = 1;
        this.add(textNom, c);

        String field;
            field = "ID_COMMERCIAL";
        // Commercial
        c.weightx = 0;
        c.gridx++;
        this.add(new JLabel(getLabelFor(field), SwingConstants.RIGHT), c);

        ElementComboBox commSel = new ElementComboBox(false, 25);
        c.gridx = GridBagConstraints.RELATIVE;
        c.gridwidth = 1;
        c.weightx = 1;
        c.weighty = 0;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.WEST;
        this.add(commSel, c);
        addRequiredSQLObject(commSel, field);

        // Table d'élément
        c.fill = GridBagConstraints.BOTH;
        c.gridy++;
        c.gridx = 0;
        c.weightx = 0;
        c.weighty = 1;
        c.gridwidth = 4;
        this.add(this.table, c);
        if (showDevise) {

            boxDevise.addValueListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    FactureFournisseurSQLComponent.this.table.setDevise(boxDevise.getSelectedRow());
                    updateLabelTauxConversion();

                }
            });

            this.fieldTaux.getDocument().addDocumentListener(new SimpleDocumentListener() {

                @Override
                public void update(DocumentEvent e) {
                    BigDecimal tauxConversion = null;
                    if (FactureFournisseurSQLComponent.this.fieldTaux.getText().trim().length() > 0) {
                        tauxConversion = new BigDecimal(FactureFournisseurSQLComponent.this.fieldTaux.getText());
                    }
                    FactureFournisseurSQLComponent.this.table.setTauxConversion(tauxConversion);
                    updateLabelTauxConversion();
                }
            });
        }

        this.fourn.addModelListener("wantedID", new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                FactureFournisseurSQLComponent.this.table.setFournisseur(FactureFournisseurSQLComponent.this.fourn.getSelectedRow());
                if (!isFilling()) {
                    SQLRow row = FactureFournisseurSQLComponent.this.fourn.getSelectedRow();
                    if (row != null && !row.isUndefined()) {
                        row.fetchValues();
                        if (!row.isForeignEmpty("ID_COMPTE_PCE_CHARGE")) {
                            FactureFournisseurSQLComponent.this.comptePCE.setValue(row.getForeign("ID_COMPTE_PCE_CHARGE"));
                        }
                    }
                }
            }
        });
        // Bottom
        c.gridy++;
        c.weighty = 0;
        this.add(getBottomPanel(), c);

        ModeDeReglementSQLComponent modeReglComp = (ModeDeReglementSQLComponent) this.eltModeRegl.getSQLChild();
        modeReglComp.addDateCompListener(this.dateCommande);

        // Modèle, visualiser, imprimer..
        c.gridx = 0;
        c.gridy++;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.SOUTHEAST;
        c.gridwidth = GridBagConstraints.REMAINDER;

        this.panelOO = new PanelOOSQLComponent(this);
        this.add(this.panelOO, c);

        addSQLObject(textNom, "NOM");
        addRequiredSQLObject(this.dateCommande, "DATE");
        addRequiredSQLObject(this.numero, "NUMERO");
        addSQLObject(this.infos, "INFOS");

        DefaultGridBagConstraints.lockMinimumSize(this.fourn);
        DefaultGridBagConstraints.lockMinimumSize(commSel);
    }

    private void updateLabelTauxConversion() {
        String result = "";
        if (this.fieldTaux.getText().trim().length() == 0 && this.table.getDevise() != null && !this.table.getDevise().isUndefined()) {
            CurrencyConverter converter = new CurrencyConverter();
            BigDecimal taux = converter.convert(BigDecimal.ONE, converter.getCompanyCurrencyCode(), this.table.getDevise().getString("CODE"), this.table.getDateDevise(), false);
            result = "(" + taux + ")";
        } else {
            result = "(" + this.fieldTaux.getText() + ")";
        }
        this.labelTaux.setText(result);
    }

    private JPanel getBottomPanel() {
        final JPanel panel = new JPanel(new GridBagLayout());
        final GridBagConstraints c = new DefaultGridBagConstraints();

        JTabbedPane tabs = new JTabbedPane();

        JPanel mainBottomPanel = new JPanel();
        mainBottomPanel.setOpaque(false);
        tabs.add(mainBottomPanel, "Règlements et caractéristiques");
        final JScrollPane scrollPane = new JScrollPane(this.infos);
        scrollPane.setBorder(null);

        tabs.add(scrollPane, getLabelFor("INFOS"));
        c.gridx = 0;
        c.weightx = 1;
        c.anchor = GridBagConstraints.WEST;
        c.fill = GridBagConstraints.BOTH;
        panel.add(tabs, c);

        mainBottomPanel.setLayout(new GridBagLayout());
        GridBagConstraints cMainBottomPanel = new DefaultGridBagConstraints();

        // Colonne 1 : Infos

        cMainBottomPanel.weighty = 0;
        cMainBottomPanel.weightx = 0;
        cMainBottomPanel.fill = GridBagConstraints.BOTH;

        this.addView("ID_MODE_REGLEMENT", REQ + ";" + DEC + ";" + SEP);
        this.eltModeRegl = (ElementSQLObject) this.getView("ID_MODE_REGLEMENT");

        c.gridx++;
        c.fill = GridBagConstraints.NONE;
        c.weightx = 1;
        c.weighty = 1;
        this.eltModeRegl.setOpaque(false);
        mainBottomPanel.add(this.eltModeRegl, cMainBottomPanel);

        // Colonne 2 : Poids & autres
        JPanel column2 = new JPanel();
        column2.setOpaque(false);
        cMainBottomPanel.gridx++;
        cMainBottomPanel.weightx = 0;
        mainBottomPanel.add(column2, cMainBottomPanel);

        column2.setLayout(new GridBagLayout());
        GridBagConstraints c2 = new DefaultGridBagConstraints();

        c2.weightx = 0;
        c2.weighty = 0;
        c2.gridwidth = 1;
        c2.gridheight = 1;
        c2.fill = GridBagConstraints.HORIZONTAL;
        c2.anchor = GridBagConstraints.NORTHEAST;
        // Poids
        DefaultProps props = DefaultNXProps.getInstance();
        Boolean poidsVisible = props.getBooleanValue("ArticleShowPoids");
        if (poidsVisible) {
            column2.add(new JLabel(getLabelFor("T_POIDS"), SwingConstants.RIGHT), c2);
            final JTextField textPoidsTotal = new JTextField(8);
            textPoidsTotal.setEnabled(false);
            textPoidsTotal.setHorizontalAlignment(JTextField.RIGHT);
            textPoidsTotal.setDisabledTextColor(Color.BLACK);
            c2.weightx = 1;
            c2.gridx++;
            column2.add(textPoidsTotal, c2);
            DefaultGridBagConstraints.lockMinimumSize(textPoidsTotal);
            addSQLObject(textPoidsTotal, "T_POIDS");

            this.table.getModel().addTableModelListener(new TableModelListener() {

                public void tableChanged(TableModelEvent e) {
                    textPoidsTotal.setText(String.valueOf(FactureFournisseurSQLComponent.this.table.getPoidsTotal()));
                }
            });

        } else {
            addSQLObject(new JTextField(), "T_POIDS");
        }

        DeviseField textPortHT = new DeviseField();
        ElementComboBox comboTaxePort = new ElementComboBox();
        DeviseField textRemiseHT = new DeviseField();

        if (getTable().contains("PORT_HT")) {
            // Port HT
            addSQLObject(textPortHT, "PORT_HT");
            c2.gridx = 0;
            c2.gridy++;
            c2.weightx = 0;
            column2.add(new JLabel(getLabelFor("PORT_HT"), SwingConstants.RIGHT), c2);
            textPortHT.setHorizontalAlignment(JTextField.RIGHT);
            c2.gridx++;
            c2.weightx = 1;
            column2.add(textPortHT, c2);
            // TVA sur port
            c2.gridy++;
            c2.gridx = 0;
            c2.weightx = 0;
            addRequiredSQLObject(comboTaxePort, "ID_TAXE_PORT");
            column2.add(new JLabel(getLabelFor("ID_TAXE_PORT"), SwingConstants.RIGHT), c2);
            c2.gridx++;
            c2.weightx = 0;
            column2.add(comboTaxePort, c2);
            // Remise HT
            addSQLObject(textRemiseHT, "REMISE_HT");
            c2.gridx = 0;
            c2.gridy++;
            c2.weightx = 0;
            column2.add(new JLabel(getLabelFor("REMISE_HT"), SwingConstants.RIGHT), c2);
            textRemiseHT.setHorizontalAlignment(JTextField.RIGHT);
            c2.gridx++;
            c2.weightx = 1;
            column2.add(textRemiseHT, c2);

        }
        final JTextField textTvaAdujs;
        if (getTable().contains("TVA_ADJUSTMENT")) {
            textTvaAdujs = new JTextField(15);
            final JLabel labelTvaAdujst = new JLabel(getLabelFor("TVA_ADJUSTMENT"), SwingConstants.RIGHT);
            c2.gridx = 0;
            c2.gridy++;
            c2.weightx = 0;
            column2.add(labelTvaAdujst, c2);
            c2.gridx++;
            c2.weightx = 1;
            column2.add(textTvaAdujs, c2);
            addView(textTvaAdujs, "TVA_ADJUSTMENT");

            DefaultGridBagConstraints.lockMinimumSize(textTvaAdujs);
        } else {
            textTvaAdujs = null;
        }

        c2.gridy++;
        c2.gridx = 0;
        column2.add(new JLabel("Avoirs", SwingConstants.RIGHT), c2);

        c2.gridx++;
        c2.fill = GridBagConstraints.NONE;
        c2.anchor = GridBagConstraints.EAST;
        column2.add(createPanelAvoir(), c2);

        c2.gridy++;
        column2.add(getModuleTotalPanel(), c2);
        c2.gridy++;
        JPanel filler = new JPanel();
        filler.setOpaque(false);
        c2.weighty = 1;
        column2.add(filler, c2);

        // Colonne 4 Total

        DeviseField fieldHT = new DeviseField();
        DeviseField fieldEco = new DeviseField();
        DeviseField fieldTVA = new DeviseField();
        DeviseField fieldDevise = new DeviseField();
        DeviseField fieldService = new DeviseField();
        fieldHT.setOpaque(false);
        fieldTVA.setOpaque(false);
        this.fieldTTC.setOpaque(false);
        fieldService.setOpaque(false);
        addRequiredSQLObject(fieldDevise, "T_DEVISE");
        addRequiredSQLObject(fieldEco, "T_ECO_CONTRIBUTION");
        addRequiredSQLObject(fieldHT, "T_HT");
        addRequiredSQLObject(fieldTVA, "T_TVA");

        addRequiredSQLObject(this.fieldTTC, "T_TTC");
        addRequiredSQLObject(fieldService, "T_SERVICE");

        this.fieldTTC.getDocument().addDocumentListener(new SimpleDocumentListener() {
            @Override
            public void update(DocumentEvent e) {
                refreshText();
            }

        });

        // Disable
        this.allowEditable("T_ECO_CONTRIBUTION", false);
        this.allowEditable("T_HT", false);
        this.allowEditable("T_TVA", false);
        this.allowEditable("T_TTC", false);
        this.allowEditable("T_SERVICE", false);
        this.allowEditable("T_POIDS", false);

        final TotalPanel totalTTC = new TotalPanel(this.table, fieldEco, fieldHT, fieldTVA, this.fieldTTC, textPortHT, textRemiseHT, fieldService, null, fieldDevise, null, null,
                (getTable().contains("ID_TAXE_PORT") ? comboTaxePort : null), null);
        if (textTvaAdujs != null) {
            totalTTC.setTextFixTVA(textTvaAdujs);
            textTvaAdujs.getDocument().addDocumentListener(new SimpleDocumentListener() {
                @Override
                public void update(final DocumentEvent e) {
                    final String text = textTvaAdujs.getText();
                    if (text != null && text.trim().length() > 0) {
                        if (!text.trim().equals("-")) {
                            BigDecimal tvaFix = new BigDecimal(text);
                            if (tvaFix.abs().compareTo(new BigDecimal(0.05)) > 0) {
                                final String limitedFix;
                                if (tvaFix.signum() > 0) {
                                    limitedFix = tvaFix.min(new BigDecimal(0.05)).toString();
                                } else {
                                    limitedFix = tvaFix.max(new BigDecimal(-0.05)).toString();
                                }
                                SwingUtilities.invokeLater(new Runnable() {
                                    @Override
                                    public void run() {

                                        textTvaAdujs.setText(limitedFix);
                                    }
                                });
                            }
                        }
                    }
                    totalTTC.updateTotal();
                }
            });
        }
        c.gridx++;
        c.gridy = 0;
        c.gridwidth = 1;
        c.gridheight = 1;
        c.anchor = GridBagConstraints.NORTHEAST;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weighty = 0;
        DefaultGridBagConstraints.lockMinimumSize(totalTTC);

        panel.add(totalTTC, c);

        this.fourn.addModelListener("wantedID", new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                final SQLRow selectedRow2 = FactureFournisseurSQLComponent.this.fourn.getSelectedRow();
                if (selectedRow2 != null && !selectedRow2.isUndefined()) {
                    totalTTC.setIntraComm(selectedRow2.getBoolean("UE"));
                } else {
                    totalTTC.setIntraComm(false);
                }

            }
        });

        textPortHT.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }

            public void removeUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }

            public void insertUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }
        });

        comboTaxePort.addValueListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                totalTTC.updateTotal();
            }
        });

        textRemiseHT.getDocument().addDocumentListener(new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }

            public void removeUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }

            public void insertUpdate(DocumentEvent e) {
                totalTTC.updateTotal();
            }
        });

        ModeDeReglementSQLComponent modeReglComp = (ModeDeReglementSQLComponent) this.eltModeRegl.getSQLChild();
        modeReglComp.addDateCompListener(this.dateCommande);
        return panel;
    }

    protected JPanel getModuleTotalPanel() {

        return AutoHideListener.listen(new JPanel());
    }

    public int insert(SQLRow order) {

        final SQLTable tableNum = getTable().getTable("NUMEROTATION_AUTO");
        // incrémentation du numéro auto
        if (tableNum.contains("FACTURE_FOURNISSEUR_START") && NumerotationAutoSQLElement.getNextNumero(getElement().getClass(), new Date()).equalsIgnoreCase(this.numero.getText().trim())) {
            SQLRowValues rowVals = new SQLRowValues(tableNum);

            final SQLRow rowNumAuto = tableNum.getRow(2);
            if (rowNumAuto.getObject("FACTURE_FOURNISSEUR_START") != null) {
                int val = rowNumAuto.getInt("FACTURE_FOURNISSEUR_START");
                val++;
                rowVals.put("FACTURE_FOURNISSEUR_START", new Integer(val));

                try {
                    rowVals.update(2);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        int idFacture = getSelectedID();
        idFacture = super.insert(order);
        this.table.updateField("ID_FACTURE_FOURNISSEUR", idFacture);

        // Création des articles
        this.table.createArticle(idFacture, this.getElement());

        final SQLRow rowA = getTable().getRow(idFacture);
        new GenerationMvtFactureFournisseur(rowA);

        final FactureFournisseurXmlSheet sheet = new FactureFournisseurXmlSheet(rowA);
        sheet.createDocumentAsynchronous();
        sheet.showPrintAndExportAsynchronous(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected(), true);

        commitAvoir(null, rowA);

        return idFacture;
    }

    @Override
    public void update() {

        SQLRow rowFactureOld = getTable().getRow(getSelectedID());
        super.update();
        SQLRow row = getTable().getRow(getSelectedID());
        this.table.updateField("ID_FACTURE_FOURNISSEUR", row.getID());
        this.table.createArticle(getSelectedID(), this.getElement());

        boolean createCompte = (rowFactureOld.getForeignID("ID_FOURNISSEUR") != row.getForeignID("ID_FOURNISSEUR"));
        createCompte = createCompte || (rowFactureOld.getForeignID("ID_COMPTE_PCE") != row.getForeignID("ID_COMPTE_PCE"));
        createCompte = createCompte || rowFactureOld.getLong("T_TTC") != row.getLong("T_TTC");
        createCompte = createCompte || rowFactureOld.getLong("T_TVA") != row.getLong("T_TVA");
        createCompte = createCompte || rowFactureOld.getLong("T_HT") != row.getLong("T_HT");
        if (!createCompte) {
            int a = JOptionPane.showConfirmDialog(null, "Voulez vous recréer la comptabilité ?", "Comptabilité", JOptionPane.YES_NO_OPTION);
            createCompte = a == JOptionPane.YES_OPTION;
        }
        if (createCompte) {
            int idMvt = (row.getObject("ID_MOUVEMENT") == null ? 1 : row.getInt("ID_MOUVEMENT"));
            System.err.println("__________***************** UPDATE" + idMvt);

            // on supprime tout ce qui est lié à la facture
            EcritureSQLElement eltEcr = (EcritureSQLElement) Configuration.getInstance().getDirectory().getElement("ECRITURE");
            eltEcr.archiveMouvementProfondeur(idMvt, false);
            if (idMvt > 1) {
                new GenerationMvtFactureFournisseur(row, idMvt);
            } else {
                new GenerationMvtFactureFournisseur(row);
            }
        }
        final FactureFournisseurXmlSheet sheet = new FactureFournisseurXmlSheet(row);
        sheet.createDocumentAsynchronous();
        sheet.showPrintAndExportAsynchronous(this.panelOO.isVisualisationSelected(), this.panelOO.isImpressionSelected(), true);
        commitAvoir(rowFactureOld, row);
    }

    public void commitAvoir(SQLRow rowFactureOld, SQLRow rowFacture) {

        try {
            List<String> fieldsAvoir = Arrays.asList("ID_AVOIR_FOURNISSEUR", "ID_AVOIR_FOURNISSEUR_2");
            for (String field : fieldsAvoir) {

                if (rowFactureOld != null && rowFactureOld.getObject(field) != null && !rowFactureOld.isForeignEmpty(field)
                        && (rowFacture.getObject(field) == null || rowFacture.isForeignEmpty(field))) {

                    SQLRow rowAvoir = rowFactureOld.getForeignRow(field);

                    SQLRowValues rowVals = rowAvoir.createEmptyUpdateRow();

                    // Soldé
                    rowVals.put("SOLDE", Boolean.FALSE);

                    rowVals.update();

                }

                // on solde l'avoir
                if (rowFacture.getObject(field) != null && !rowFacture.isForeignEmpty(field)) {

                    SQLRow rowAvoir = rowFacture.getForeignRow(field);

                    SQLRowValues rowVals = rowAvoir.createEmptyUpdateRow();
                    rowVals.put("SOLDE", Boolean.TRUE);

                    rowVals.update();

                }
            }
        } catch (SQLException e) {
            ExceptionHandler.handle("Erreur lors la mise à jour de l'avoir associée!", e);
        }
    }

    public void setDefaults() {
        this.resetValue();
        this.table.getModel().clearRows();
    }

    @Override
    protected SQLRowValues createDefaults() {
        SQLRowValues rowVals = new SQLRowValues(getTable());
        rowVals.put("T_POIDS", 0.0F);
        // User
        // SQLSelect sel = new SQLSelect(Configuration.getInstance().getBase());
        SQLElement eltComm = Configuration.getInstance().getDirectory().getElement("COMMERCIAL");
        int idUser = UserManager.getInstance().getCurrentUser().getId();

        // sel.addSelect(eltComm.getTable().getKey());
        // sel.setWhere(new Where(eltComm.getTable().getField("ID_USER_COMMON"), "=", idUser));
        // List<SQLRow> rowsComm = (List<SQLRow>)
        // Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), new
        // SQLRowListRSH(eltComm.getTable()));
        SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));

        if (rowsComm != null) {
            rowVals.put("ID_COMMERCIAL", rowsComm.getID());
        }

        if (getTable().getTable("NUMEROTATION_AUTO").contains("FACTURE_FOURNISSEUR_START")) {
            rowVals.put("NUMERO", NumerotationAutoSQLElement.getNextNumero(getElement().getClass(), new Date()));
        }

        rowVals.put("T_HT", Long.valueOf(0));
        rowVals.put("T_SERVICE", Long.valueOf(0));
        rowVals.put("T_DEVISE", Long.valueOf(0));
        rowVals.put("T_TVA", Long.valueOf(0));
        rowVals.put("T_TTC", Long.valueOf(0));
        // rowVals.put("NUMERO",
        // NumerotationAutoSQLElement.getNextNumero(CommandeSQLElement.class));

        if (getTable().contains("ID_TAXE_PORT")) {
            rowVals.put("ID_TAXE_PORT", TaxeCache.getCache().getFirstTaxe().getID());
        }

        return rowVals;
    }

    @Override
    public RowValuesTable getRowValuesTable() {
        return this.table.getRowValuesTable();
    }

    private JPanel createPanelAvoir() {
        JPanel panelAvoir = new JPanel(new GridBagLayout());
        panelAvoir.setOpaque(false);
        GridBagConstraints cA = new DefaultGridBagConstraints();
        JLabel labelAvoir = new JLabel(getLabelFor("ID_AVOIR_FOURNISSEUR"));
        labelAvoir.setHorizontalAlignment(SwingConstants.RIGHT);
        cA.weightx = 1;
        labelAvoir.setHorizontalAlignment(SwingConstants.RIGHT);
        panelAvoir.add(labelAvoir, cA);
        cA.weightx = 0;
        cA.gridx++;
        this.avoirFourn = new ElementComboBox();
        this.avoirFourn.setAddIconVisible(false);
        panelAvoir.add(this.avoirFourn, cA);
        final JLabel labelTotalAvoir = new JLabel("Total à régler");
        this.textNetAPayer.setEditable(false);
        cA.gridx++;
        cA.weightx = 0;
        panelAvoir.add(labelTotalAvoir, cA);
        cA.gridx++;
        cA.weightx = 0;
        panelAvoir.add(this.textNetAPayer, cA);
        addView(this.textNetAPayer, "NET_A_PAYER");
        this.textNetAPayer.setHorizontalAlignment(SwingConstants.RIGHT);

        JLabel labelAvoir2 = new JLabel(getLabelFor("ID_AVOIR_FOURNISSEUR_2"));
        labelAvoir.setHorizontalAlignment(SwingConstants.RIGHT);
        cA.gridx = 0;
        cA.gridy++;
        cA.weightx = 1;
        labelAvoir.setHorizontalAlignment(SwingConstants.RIGHT);
        panelAvoir.add(labelAvoir2, cA);
        cA.weightx = 0;
        cA.gridx++;
        this.avoirFourn2 = new ElementComboBox();
        this.avoirFourn2.setAddIconVisible(false);
        panelAvoir.add(this.avoirFourn2, cA);

        addView(this.avoirFourn2, "ID_AVOIR_FOURNISSEUR_2");
        addView(this.avoirFourn, "ID_AVOIR_FOURNISSEUR");
        addView(this.avoirTTC, "AVOIR_TTC");
        this.avoirFourn.addModelListener("wantedID", new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                if (!isFilling()) {
                    refreshText();
                }
            }

        });
        this.avoirFourn2.addModelListener("wantedID", new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                if (!isFilling()) {
                    refreshText();
                }
            }

        });
        return panelAvoir;
    }

    private void refreshText() {
        Number n = this.fieldTTC.getValue();
        long totalAvoirTTC = 0;
        long netAPayer = 0;
        if (n != null) {
            netAPayer = n.longValue();
        }

        List<ElementComboBox> boxAvoir = Arrays.asList(this.avoirFourn, this.avoirFourn2);
        for (ElementComboBox elementComboBox : boxAvoir) {
            if (elementComboBox.getWantedID() > 1) {
                SQLTable tableAvoir = getTable().getForeignTable("ID_AVOIR_FOURNISSEUR");
                if (n != null) {
                    SQLRow rowAvoir = tableAvoir.getRow(elementComboBox.getWantedID());
                    long totalAvoir = ((Number) rowAvoir.getObject("MONTANT_TTC")).longValue();
                    if (getSelectedID() > 1) {
                        SQLRow row = getTable().getRow(getSelectedID());
                        int idAvoirOld = row.getInt("ID_AVOIR_FOURNISSEUR");
                        if (idAvoirOld == rowAvoir.getID()) {
                            totalAvoir += Long.valueOf(row.getObject("AVOIR_TTC").toString());
                        }
                    }

                    long l = netAPayer - totalAvoir;
                    if (l < 0) {
                        l = 0;
                        totalAvoirTTC = netAPayer;
                    } else {
                        totalAvoirTTC = totalAvoir;
                    }
                    netAPayer = l;
                }
            }
        }

        this.textNetAPayer.setValue(netAPayer);
        this.avoirTTC.setValue(totalAvoirTTC);
    }

    @Override
    protected void refreshAfterSelect(SQLRowAccessor rSource) {
        if (this.dateCommande.getValue() != null) {
            this.table.setDateDevise(this.dateCommande.getValue());
            updateLabelTauxConversion();
        }

    }

    public void loadFactureExistante(int idFacture) {

        SQLElement fact = getElement();
        SQLElement factElt = getElement().getDirectory().getElement("FACTURE_FOURNISSEUR_ELEMENT");

        // On duplique la facture
        if (idFacture > 1) {
            SQLRow row = fact.getTable().getRow(idFacture);
            SQLRowValues rowVals = new SQLRowValues(fact.getTable());
            rowVals.put("ID_FOURNISSEUR", row.getForeignID("ID_FOURNISSEUR"));
            if (!row.isForeignEmpty("ID_COMPTE_PCE")) {
                rowVals.put("ID_COMPTE_PCE", row.getForeignID("ID_COMPTE_PCE"));
            }

            rowVals.put("NOM", row.getObject("NOM"));
            this.select(rowVals);
        }

        // On duplique les elements de facture
        List<SQLRow> myListItem = fact.getTable().getRow(idFacture).getReferentRows(factElt.getTable());

        if (myListItem.size() != 0) {
            this.table.getModel().clearRows();

            for (SQLRow rowElt : myListItem) {

                SQLRowValues rowVals = rowElt.createUpdateRow();
                rowVals.clearPrimaryKeys();
                if (rowVals.getTable().contains("ID_COMMANDE_ELEMENT")) {
                    rowVals.putEmptyLink("ID_COMMANDE_ELEMENT");
                }
                if (rowVals.getTable().contains("ID_BON_RECEPTION_ELEMENT")) {
                    rowVals.putEmptyLink("ID_BON_RECEPTION_ELEMENT");
                }
                this.table.getModel().addRow(rowVals);
                int rowIndex = this.table.getModel().getRowCount() - 1;
                this.table.getModel().fireTableModelModified(rowIndex);
            }
        } else {
            this.table.getModel().clearRows();
        }
        this.table.getModel().fireTableDataChanged();
        this.table.repaint();
    }

}