Dépôt officiel du code source de l'ERP OpenConcerto
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.core.supplychain.stock.element;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.sales.product.action.InventairePanel;
import org.openconcerto.erp.generationDoc.gestcomm.FicheArticleXmlSheet;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.sql.element.BaseSQLComponent;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.users.rights.UserRightsManager;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.IListeAction.IListeEvent;
import org.openconcerto.sql.view.list.RowAction.PredicateRowAction;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.DecimalUtils;
import org.openconcerto.utils.ListMap;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class StockSQLElement extends ComptaSQLConfElement {
public StockSQLElement() {
super("STOCK", "un stock", "stocks");
getRowActions().addAll(new MouseSheetXmlListeListener(this, FicheArticleXmlSheet.class).getRowActions());
PredicateRowAction stock = new PredicateRowAction(new AbstractAction("Mettre à jour les stocks") {
@Override
public void actionPerformed(ActionEvent e) {
if (UserRightsManager.getCurrentUserRights().canAdd(getTable().getDBRoot().getTable("STOCK"))) {
final PanelFrame p = new PanelFrame(new InventairePanel(IListe.get(e), IListe.get(e).getSelectedRows()), "Mise à jour des stocks");
FrameUtil.show(p);
} else {
JOptionPane.showMessageDialog(null, "Vous n'avez les droits suffisants pour modifier manuellement les stocks!");
}
}
}, true, false);
stock.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
getRowActions().add(stock);
PredicateRowAction cmd = new PredicateRowAction(new AbstractAction("Passer une commande") {
@Override
public void actionPerformed(ActionEvent e) {
transfertCommande(IListe.get(e).getSelectedRowAccessors());
}
}, true, false);
cmd.setPredicate(IListeEvent.getNonEmptySelectionPredicate());
getRowActions().add(cmd);
}
protected List<String> getListFields() {
return Arrays.asList("ID_ARTICLE", "QTE_MIN", "QTE_TH", "QTE_REEL", "QTE_LIV_ATTENTE", "QTE_RECEPT_ATTENTE", "ID_DEPOT_STOCK");
}
@Override
public Set<String> getReadOnlyFields() {
Set<String> s = new HashSet<>();
if (getTable().contains("ID_ARTICLE")) {
s.add("ID_ARTICLE");
}
s.add("QTE_TH");
s.add("QTE_REEL");
s.add("QTE_LIV_ATTENTE");
s.add("QTE_RECEPT_ATTENTE");
if (getTable().contains("ID_DEPOT_STOCK")) {
s.add("ID_DEPOT_STOCK");
}
return s;
}
@Override
protected List<String> getComboFields() {
return Arrays.asList("ID_DEPOT_STOCK", "QTE_REEL");
}
@Override
protected String getParentFFName() {
return "ID_ARTICLE";
}
@Override
public ListMap<String, String> getShowAs() {
if (getTable().contains("ID_DEPOT_STOCK")) {
return ListMap.singleton(null, "QTE_TH", "QTE_REEL", "QTE_MIN", "QTE_LIV_ATTENTE", "QTE_RECEPT_ATTENTE", "ID_DEPOT_STOCK");
} else {
return ListMap.singleton(null, "QTE_TH", "QTE_REEL", "QTE_LIV_ATTENTE", "QTE_RECEPT_ATTENTE");
}
}
public static SQLRowAccessor getStockFetched(SQLRowAccessor rowValsSource) {
SQLRowAccessor rowStock = null;
final int idDepot;
if (rowValsSource.getForeign("ID_DEPOT_STOCK") != null && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
} else {
idDepot = rowValsSource.getForeign("ID_ARTICLE").getForeignID("ID_DEPOT_STOCK");
}
SQLTable stockTable = rowValsSource.getTable().getTable("STOCK");
Collection<? extends SQLRowAccessor> rows = rowValsSource.getForeign("ID_ARTICLE").getReferentRows(stockTable);
for (SQLRowAccessor sqlRowAccessor : rows) {
if (sqlRowAccessor.getForeignID("ID_DEPOT_STOCK") == idDepot) {
rowStock = sqlRowAccessor;
break;
}
}
return rowStock;
}
public static SQLRowAccessor getStock(SQLRowAccessor rowValsSource) throws SQLException {
SQLRowAccessor rowStock = null;
final int idDepot;
if (rowValsSource.getForeign("ID_DEPOT_STOCK") != null && !rowValsSource.isForeignEmpty("ID_DEPOT_STOCK")) {
idDepot = rowValsSource.getForeignID("ID_DEPOT_STOCK");
} else {
SQLRowAccessor rowValsArt = rowValsSource.getForeign("ID_ARTICLE");
if (rowValsArt.getObject("ID_DEPOT_STOCK") == null) {
rowValsArt = rowValsArt.asRow();
((SQLRow) rowValsArt).fetchValues();
System.err.println("REFETCH ARTICLE");
Thread.dumpStack();
}
idDepot = rowValsArt.getForeignID("ID_DEPOT_STOCK");
}
final int idArticle = rowValsSource.getForeignID("ID_ARTICLE");
DBRoot root = rowValsSource.getTable().getDBRoot();
SQLTable stockTable = root.getTable("STOCK");
SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
putRowValuesStock.putNulls(stockTable.getTable().getFieldsName());
SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
Where w = new Where(stockTable.getField("ID_DEPOT_STOCK"), "=", idDepot);
Where w2 = new Where(stockTable.getField("ID_ARTICLE"), "=", idArticle);
Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
if (rowValsResult.isEmpty()) {
SQLRowValues rowValsStock = new SQLRowValues(stockTable);
rowValsStock.put("ID_ARTICLE", idArticle);
rowValsStock.put("ID_DEPOT_STOCK", idDepot);
rowValsStock.put("QTE_TH", 0F);
rowValsStock.put("QTE_REEL", 0F);
rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
rowValsStock.put("QTE_LIV_ATTENTE", 0F);
rowStock = rowValsStock.insert();
if (idDepot == DepotStockSQLElement.DEFAULT_ID) {
rowValsSource.getForeign("ID_ARTICLE").createEmptyUpdateRow().put("ID_STOCK", rowStock.getID()).commit();
}
} else if (rowValsResult.size() == 1) {
rowStock = rowValsResult.iterator().next();
} else if (rowValsResult.size() > 1) {
throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + rowValsSource.getForeign("ID_ARTICLE").getID() + " Depot " + idDepot);
}
return rowStock;
}
/**
* Stock d'un article dans un dépôt donné
*
* @param idDepot dépôt
* @param idArticle article
* @param createIfMissing initialisation du stock à 0 si n'existe pas
* @return le stock (null si createIfMissing à false et que que le stock n'existe pas)
*/
public SQLRow getStock(int idDepot, int idArticle, boolean createIfMissing) throws SQLException {
final SQLTable stockTable = getTable();
final SQLRowValues putRowValuesStock = new SQLRowValues(stockTable);
putRowValuesStock.putNulls(stockTable.getFieldsName());
final SQLRowValuesListFetcher fetch = SQLRowValuesListFetcher.create(putRowValuesStock);
final Where w = new Where(stockTable.getField("ID_DEPOT_STOCK"), "=", idDepot);
final Where w2 = new Where(stockTable.getField("ID_ARTICLE"), "=", idArticle);
final Collection<SQLRowValues> rowValsResult = fetch.fetch(w.and(w2));
SQLRow result;
if (rowValsResult.isEmpty()) {
if (!createIfMissing) {
return null;
}
final SQLRowValues rowValsStock = new SQLRowValues(stockTable);
rowValsStock.put("ID_ARTICLE", idArticle);
rowValsStock.put("ID_DEPOT_STOCK", idDepot);
rowValsStock.put("QTE_TH", 0F);
rowValsStock.put("QTE_REEL", 0F);
rowValsStock.put("QTE_RECEPT_ATTENTE", 0F);
rowValsStock.put("QTE_LIV_ATTENTE", 0F);
result = rowValsStock.insert();
} else if (rowValsResult.size() == 1) {
result = rowValsResult.iterator().next().asRow();
} else {
throw new IllegalStateException("2 lignes de stocks pour le même dépôt! Article " + idArticle + " Depot " + idDepot);
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.openconcerto.devis.SQLElement#getComponent()
*/
public SQLComponent createComponent() {
return new BaseSQLComponent(this) {
public void addViews() {
this.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
// Article
JLabel labelA = new JLabel(getLabelFor("ID_ARTICLE"));
c.weightx = 0;
this.add(labelA, c);
c.gridx++;
ElementComboBox boxA = new ElementComboBox();
this.add(boxA, c);
// Depot
JLabel labelD = new JLabel(getLabelFor("ID_DEPOT_STOCK"));
c.gridx++;
c.weightx = 0;
this.add(labelD, c);
c.gridx++;
ElementComboBox boxD = new ElementComboBox();
this.add(boxD, c);
// Qté Réelle
JLabel labelQteR = new JLabel(getLabelFor("QTE_REEL"));
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelQteR, c);
c.gridx++;
JTextField textQteReel = new JTextField(6);
this.add(textQteReel, c);
// Qté Réelle
JLabel labelQteT = new JLabel(getLabelFor("QTE_TH"));
c.gridx++;
c.weightx = 0;
this.add(labelQteT, c);
c.gridx++;
JTextField textQteT = new JTextField(6);
this.add(textQteT, c);
// Qté Réelle
JLabel labelQteRe = new JLabel(getLabelFor("QTE_RECEPT_ATTENTE"));
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelQteRe, c);
c.gridx++;
JTextField textQteRe = new JTextField(6);
this.add(textQteRe, c);
JLabel labelQteL = new JLabel(getLabelFor("QTE_LIV_ATTENTE"));
c.gridx++;
c.weightx = 0;
this.add(labelQteL, c);
c.gridx++;
JTextField textQteL = new JTextField(6);
this.add(textQteL, c);
// Qté Min
JLabel labelQteTMin = new JLabel(getLabelFor("QTE_MIN"));
c.gridx = 0;
c.gridy++;
c.weightx = 0;
this.add(labelQteTMin, c);
c.gridx++;
JTextField textQteMin = new JTextField(6);
this.add(textQteMin, c);
this.addSQLObject(textQteReel, "QTE_REEL");
this.addSQLObject(textQteT, "QTE_TH");
this.addSQLObject(textQteMin, "QTE_MIN");
this.addSQLObject(textQteL, "QTE_LIV_ATTENTE");
this.addSQLObject(textQteRe, "QTE_RECEPT_ATTENTE");
this.addSQLObject(boxA, "ID_ARTICLE");
this.addSQLObject(boxD, "ID_DEPOT_STOCK");
}
};
}
/**
* Transfert d'une commande en commande fournisseur
*
* @param commandeID
*/
public void transfertCommande(List<SQLRowAccessor> rows) {
ComptaPropsConfiguration.getInstanceCompta().getNonInteractiveSQLExecutor().execute(new Runnable() {
@Override
public void run() {
SQLTable tableCmdElt = getDirectory().getElement("COMMANDE_ELEMENT").getTable();
SQLElement eltArticle = getDirectory().getElement("ARTICLE");
final ListMap<SQLRow, SQLRowValues> map = new ListMap<SQLRow, SQLRowValues>();
for (SQLRowAccessor sqlRow : rows) {
SQLRowAccessor rowArticleFind = sqlRow.getForeign("ID_ARTICLE");
int qte = 1;
BigDecimal qteUV = BigDecimal.ONE;
qte = -Math.round(sqlRow.getFloat("QTE_TH") - sqlRow.getFloat("QTE_MIN"));
SQLInjector inj = SQLInjector.getInjector(eltArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind.asRow()));
rowValsElt.put("ID_DEPOT_STOCK", sqlRow.getForeignID("ID_DEPOT_STOCK"));
rowValsElt.put("QTE", qte);
rowValsElt.put("QTE_UNITAIRE", qteUV);
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
// TODO récupérer le prix depuis les tarifs d'achat
rowValsElt.put("T_PA_HT", ((BigDecimal) rowValsElt.getObject("PA_HT")).multiply(new BigDecimal(rowValsElt.getInt("QTE")), DecimalUtils.HIGH_PRECISION));
rowValsElt.put("T_PA_TTC",
((BigDecimal) rowValsElt.getObject("T_PA_HT")).multiply(new BigDecimal((rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0)), DecimalUtils.HIGH_PRECISION));
final SQLRow fournisseur = rowArticleFind.asRow().getForeignRow("ID_FOURNISSEUR");
if (fournisseur != null && !fournisseur.isUndefined() && !rowArticleFind.isUndefined()) {
SQLRowValues rowValsCode = new SQLRowValues(tableCmdElt.getForeignTable("ID_CODE_FOURNISSEUR"));
rowValsCode.putNulls("ID");
final Where w = new Where(rowValsCode.getTable().getField("ID_ARTICLE"), "=", rowArticleFind.getID())
.and(new Where(rowValsCode.getTable().getField("ID_FOURNISSEUR"), "=", fournisseur.getID()));
final List<SQLRowValues> fetch = SQLRowValuesListFetcher.create(rowValsCode).fetch(w);
for (SQLRowValues sqlRowAccessor : fetch) {
rowValsElt.put("ID_CODE_FOURNISSEUR", sqlRowAccessor.getID());
}
}
map.add(fournisseur, rowValsElt);
}
MouvementStockSQLElement.createCommandeF(map, null, "");
}
});
}
@Override
protected String createCode() {
return "supplychain.stock";
}
}