18 |
ilm |
1 |
/*
|
|
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
|
|
3 |
*
|
182 |
ilm |
4 |
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
|
18 |
ilm |
5 |
*
|
|
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
|
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
|
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
|
|
9 |
* language governing permissions and limitations under the License.
|
|
|
10 |
*
|
|
|
11 |
* When distributing the software, include this License Header Notice in each file.
|
|
|
12 |
*/
|
|
|
13 |
|
|
|
14 |
package org.openconcerto.erp.core.supplychain.stock.element;
|
|
|
15 |
|
|
|
16 |
import org.openconcerto.erp.config.ComptaPropsConfiguration;
|
|
|
17 |
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
|
19 |
ilm |
18 |
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
|
174 |
ilm |
19 |
import org.openconcerto.erp.core.sales.product.element.UniteVenteArticleSQLElement;
|
182 |
ilm |
20 |
import org.openconcerto.erp.core.sales.product.model.ProductComponent;
|
19 |
ilm |
21 |
import org.openconcerto.erp.core.supplychain.order.component.CommandeSQLComponent;
|
156 |
ilm |
22 |
import org.openconcerto.erp.core.supplychain.order.ui.CommandeItemTable;
|
182 |
ilm |
23 |
import org.openconcerto.erp.core.supplychain.stock.element.StockItem.TypeStockMouvement;
|
41 |
ilm |
24 |
import org.openconcerto.erp.core.supplychain.supplier.component.MouvementStockSQLComponent;
|
142 |
ilm |
25 |
import org.openconcerto.erp.preferences.GestionArticleGlobalPreferencePanel;
|
174 |
ilm |
26 |
import org.openconcerto.erp.preferences.GestionCommercialeGlobalPreferencePanel;
|
18 |
ilm |
27 |
import org.openconcerto.sql.Configuration;
|
|
|
28 |
import org.openconcerto.sql.element.SQLComponent;
|
|
|
29 |
import org.openconcerto.sql.element.SQLElement;
|
73 |
ilm |
30 |
import org.openconcerto.sql.element.TreesOfSQLRows;
|
182 |
ilm |
31 |
import org.openconcerto.sql.model.ConnectionHandlerNoSetup;
|
|
|
32 |
import org.openconcerto.sql.model.DBRoot;
|
19 |
ilm |
33 |
import org.openconcerto.sql.model.SQLBackgroundTableCache;
|
18 |
ilm |
34 |
import org.openconcerto.sql.model.SQLBase;
|
182 |
ilm |
35 |
import org.openconcerto.sql.model.SQLDataSource;
|
19 |
ilm |
36 |
import org.openconcerto.sql.model.SQLInjector;
|
18 |
ilm |
37 |
import org.openconcerto.sql.model.SQLRow;
|
182 |
ilm |
38 |
import org.openconcerto.sql.model.SQLRowAccessor;
|
19 |
ilm |
39 |
import org.openconcerto.sql.model.SQLRowListRSH;
|
18 |
ilm |
40 |
import org.openconcerto.sql.model.SQLRowValues;
|
19 |
ilm |
41 |
import org.openconcerto.sql.model.SQLSelect;
|
18 |
ilm |
42 |
import org.openconcerto.sql.model.SQLTable;
|
19 |
ilm |
43 |
import org.openconcerto.sql.model.Where;
|
61 |
ilm |
44 |
import org.openconcerto.sql.preferences.SQLPreferences;
|
132 |
ilm |
45 |
import org.openconcerto.sql.request.ListSQLRequest;
|
19 |
ilm |
46 |
import org.openconcerto.sql.users.UserManager;
|
182 |
ilm |
47 |
import org.openconcerto.sql.utils.SQLUtils;
|
18 |
ilm |
48 |
import org.openconcerto.sql.view.EditFrame;
|
|
|
49 |
import org.openconcerto.sql.view.EditPanel;
|
19 |
ilm |
50 |
import org.openconcerto.sql.view.EditPanel.EditMode;
|
|
|
51 |
import org.openconcerto.sql.view.list.RowValuesTableModel;
|
73 |
ilm |
52 |
import org.openconcerto.ui.FrameUtil;
|
182 |
ilm |
53 |
import org.openconcerto.utils.ExceptionHandler;
|
83 |
ilm |
54 |
import org.openconcerto.utils.ListMap;
|
18 |
ilm |
55 |
|
73 |
ilm |
56 |
import java.math.BigDecimal;
|
182 |
ilm |
57 |
import java.math.RoundingMode;
|
18 |
ilm |
58 |
import java.sql.SQLException;
|
182 |
ilm |
59 |
import java.text.SimpleDateFormat;
|
18 |
ilm |
60 |
import java.util.ArrayList;
|
83 |
ilm |
61 |
import java.util.Collection;
|
185 |
ilm |
62 |
import java.util.Collections;
|
|
|
63 |
import java.util.Comparator;
|
182 |
ilm |
64 |
import java.util.Date;
|
18 |
ilm |
65 |
import java.util.List;
|
83 |
ilm |
66 |
import java.util.Map.Entry;
|
18 |
ilm |
67 |
|
174 |
ilm |
68 |
import javax.swing.JOptionPane;
|
19 |
ilm |
69 |
import javax.swing.SwingUtilities;
|
18 |
ilm |
70 |
|
182 |
ilm |
71 |
import org.apache.commons.dbutils.ResultSetHandler;
|
|
|
72 |
|
18 |
ilm |
73 |
public class MouvementStockSQLElement extends ComptaSQLConfElement {
|
|
|
74 |
|
|
|
75 |
public MouvementStockSQLElement() {
|
|
|
76 |
super("MOUVEMENT_STOCK", "un mouvement de stock", "mouvements de stock");
|
|
|
77 |
}
|
|
|
78 |
|
156 |
ilm |
79 |
@Override
|
|
|
80 |
public ListMap<String, String> getShowAs() {
|
|
|
81 |
ListMap<String, String> map = new ListMap<String, String>();
|
|
|
82 |
map.putCollection("ID_STOCK", "ID_DEPOT_STOCK");
|
|
|
83 |
return map;
|
|
|
84 |
}
|
|
|
85 |
|
18 |
ilm |
86 |
protected List<String> getListFields() {
|
|
|
87 |
final List<String> l = new ArrayList<String>();
|
156 |
ilm |
88 |
l.add("ID_STOCK");
|
18 |
ilm |
89 |
l.add("DATE");
|
|
|
90 |
l.add("NOM");
|
|
|
91 |
l.add("ID_ARTICLE");
|
|
|
92 |
l.add("QTE");
|
83 |
ilm |
93 |
l.add("REEL");
|
18 |
ilm |
94 |
return l;
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
protected List<String> getComboFields() {
|
|
|
98 |
final List<String> l = new ArrayList<String>();
|
|
|
99 |
l.add("NOM");
|
|
|
100 |
l.add("QTE");
|
|
|
101 |
return l;
|
|
|
102 |
}
|
|
|
103 |
|
|
|
104 |
/*
|
|
|
105 |
* (non-Javadoc)
|
|
|
106 |
*
|
|
|
107 |
* @see org.openconcerto.devis.SQLElement#getComponent()
|
|
|
108 |
*/
|
|
|
109 |
public SQLComponent createComponent() {
|
41 |
ilm |
110 |
return new MouvementStockSQLComponent(this);
|
18 |
ilm |
111 |
}
|
|
|
112 |
|
|
|
113 |
@Override
|
73 |
ilm |
114 |
protected void archive(TreesOfSQLRows trees, boolean cutLinks) throws SQLException {
|
|
|
115 |
super.archive(trees, cutLinks);
|
83 |
ilm |
116 |
updateStock(trees.getRows(), true);
|
|
|
117 |
|
73 |
ilm |
118 |
}
|
|
|
119 |
|
61 |
ilm |
120 |
/**
|
18 |
ilm |
121 |
* Mise à jour des stocks ajoute la quantité si archive est à false
|
|
|
122 |
*
|
|
|
123 |
* @param id mouvement stock
|
|
|
124 |
* @param archive
|
156 |
ilm |
125 |
* @throws SQLException
|
18 |
ilm |
126 |
*/
|
156 |
ilm |
127 |
public ListMap<SQLRow, SQLRowValues> updateStock(Collection<SQLRow> rowsMvt, boolean archive) throws SQLException {
|
73 |
ilm |
128 |
// FIXME: if (SwingUtilities.isEventDispatchThread()) {
|
|
|
129 |
// throw new IllegalStateException("This method must be called outside of EDT");
|
|
|
130 |
// }
|
83 |
ilm |
131 |
// Stock Reel : inc/dec QTE_REEL, inc/dec QTE_LIV_ATTENTE/inc/dec
|
|
|
132 |
// QTE_RECEPT_ATTENTE
|
|
|
133 |
// Stock Th : inc/dec QTE_TH, inc/dec QTE_LIV_ATTENTE/inc/dec
|
|
|
134 |
// QTE_RECEPT_ATTENTE
|
|
|
135 |
|
156 |
ilm |
136 |
final ListMap<SQLRow, SQLRowValues> map = new ListMap<>();
|
|
|
137 |
|
182 |
ilm |
138 |
if (rowsMvt == null || rowsMvt.isEmpty()) {
|
|
|
139 |
return map;
|
|
|
140 |
}
|
|
|
141 |
|
|
|
142 |
final DBRoot root = rowsMvt.iterator().next().getTable().getDBRoot();
|
|
|
143 |
|
|
|
144 |
final SQLTable tableCommandeElement = root.getTable("COMMANDE_ELEMENT");
|
|
|
145 |
final SQLTable tableStock = root.getTable("STOCK");
|
|
|
146 |
|
83 |
ilm |
147 |
for (SQLRow rowMvtStock : rowsMvt) {
|
18 |
ilm |
148 |
|
132 |
ilm |
149 |
boolean retour = rowMvtStock.getString("SOURCE") == null || rowMvtStock.getString("SOURCE").startsWith("AVOIR_CLIENT");
|
19 |
ilm |
150 |
// Mise à jour des stocks
|
156 |
ilm |
151 |
|
19 |
ilm |
152 |
final SQLRow rowArticle = rowMvtStock.getForeignRow("ID_ARTICLE");
|
73 |
ilm |
153 |
|
156 |
ilm |
154 |
SQLRow rowStock = rowMvtStock.getForeignRow(("ID_STOCK"));
|
|
|
155 |
if (rowStock == null || rowStock.isUndefined()) {
|
|
|
156 |
rowStock = rowArticle.getForeign("ID_STOCK");
|
|
|
157 |
}
|
|
|
158 |
|
83 |
ilm |
159 |
if (rowMvtStock.getBoolean("REEL")) {
|
|
|
160 |
float qte = rowStock.getFloat("QTE_REEL");
|
|
|
161 |
float qteMvt = rowMvtStock.getFloat("QTE");
|
18 |
ilm |
162 |
|
182 |
ilm |
163 |
SQLRowValues rowVals = new SQLRowValues(tableStock);
|
18 |
ilm |
164 |
|
83 |
ilm |
165 |
float qteNvlle;
|
|
|
166 |
float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
|
|
|
167 |
float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
|
|
|
168 |
if (archive) {
|
|
|
169 |
qteNvlle = qte - qteMvt;
|
132 |
ilm |
170 |
if (!retour) {
|
|
|
171 |
// Réception
|
|
|
172 |
if (qteMvt > 0) {
|
|
|
173 |
qteNvlleEnAttenteRecept += qteMvt;
|
|
|
174 |
} else {
|
|
|
175 |
// Livraison
|
|
|
176 |
qteNvlleEnAttenteExp -= qteMvt;
|
|
|
177 |
}
|
83 |
ilm |
178 |
}
|
|
|
179 |
} else {
|
|
|
180 |
qteNvlle = qte + qteMvt;
|
132 |
ilm |
181 |
if (!retour) {
|
|
|
182 |
// Réception
|
|
|
183 |
if (qteMvt > 0) {
|
|
|
184 |
qteNvlleEnAttenteRecept -= qteMvt;
|
|
|
185 |
} else {
|
|
|
186 |
// Livraison
|
|
|
187 |
qteNvlleEnAttenteExp += qteMvt;
|
|
|
188 |
}
|
83 |
ilm |
189 |
}
|
|
|
190 |
}
|
|
|
191 |
rowVals.put("QTE_REEL", qteNvlle);
|
|
|
192 |
rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
|
|
|
193 |
rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
|
18 |
ilm |
194 |
|
83 |
ilm |
195 |
try {
|
156 |
ilm |
196 |
rowVals.update(rowStock.getID());
|
18 |
ilm |
197 |
|
182 |
ilm |
198 |
SQLPreferences prefs = new SQLPreferences(root);
|
156 |
ilm |
199 |
boolean gestionStockMin = prefs.getBoolean(GestionArticleGlobalPreferencePanel.WARNING_STOCK_MIN, true);
|
|
|
200 |
|
|
|
201 |
if (!archive && gestionStockMin && rowStock.getObject("QTE_MIN") != null && qteNvlle < rowStock.getFloat("QTE_MIN")) {
|
|
|
202 |
// final float qteShow = qteNvlle;
|
|
|
203 |
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCommandeElement);
|
|
|
204 |
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticle));
|
|
|
205 |
rowValsElt.put("ID_STYLE", 2);
|
|
|
206 |
final SQLRow unite = rowArticle.getForeign("ID_UNITE_VENTE");
|
|
|
207 |
final float qteElt = rowStock.getFloat("QTE_MIN") - qteNvlle;
|
|
|
208 |
if (unite.isUndefined() || unite.getBoolean("A_LA_PIECE")) {
|
|
|
209 |
rowValsElt.put("QTE", Math.round(qteElt));
|
|
|
210 |
rowValsElt.put("QTE_UNITAIRE", BigDecimal.ONE);
|
|
|
211 |
} else {
|
|
|
212 |
rowValsElt.put("QTE", 1);
|
|
|
213 |
rowValsElt.put("QTE_UNITAIRE", new BigDecimal(qteElt));
|
83 |
ilm |
214 |
}
|
156 |
ilm |
215 |
rowValsElt.put("ID_TAXE", rowValsElt.getObject("ID_TAXE"));
|
|
|
216 |
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * qteElt);
|
|
|
217 |
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * qteElt);
|
|
|
218 |
rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
|
|
|
219 |
map.add(rowArticle.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
|
83 |
ilm |
220 |
}
|
|
|
221 |
} catch (SQLException e) {
|
156 |
ilm |
222 |
throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
|
83 |
ilm |
223 |
}
|
|
|
224 |
} else {
|
|
|
225 |
float qte = rowStock.getFloat("QTE_TH");
|
|
|
226 |
float qteMvt = rowMvtStock.getFloat("QTE");
|
19 |
ilm |
227 |
|
182 |
ilm |
228 |
SQLRowValues rowVals = new SQLRowValues(tableStock);
|
18 |
ilm |
229 |
|
83 |
ilm |
230 |
float qteNvlle;
|
|
|
231 |
float qteNvlleEnAttenteRecept = rowStock.getFloat("QTE_RECEPT_ATTENTE");
|
|
|
232 |
float qteNvlleEnAttenteExp = rowStock.getFloat("QTE_LIV_ATTENTE");
|
|
|
233 |
|
|
|
234 |
if (archive) {
|
|
|
235 |
qteNvlle = qte - qteMvt;
|
132 |
ilm |
236 |
if (!retour) {
|
|
|
237 |
|
|
|
238 |
// CommandeF
|
|
|
239 |
if (qteMvt > 0) {
|
|
|
240 |
qteNvlleEnAttenteRecept -= qteMvt;
|
|
|
241 |
} else {
|
|
|
242 |
// CommanceC
|
|
|
243 |
qteNvlleEnAttenteExp += qteMvt;
|
|
|
244 |
}
|
83 |
ilm |
245 |
}
|
73 |
ilm |
246 |
} else {
|
83 |
ilm |
247 |
qteNvlle = qte + qteMvt;
|
132 |
ilm |
248 |
if (!retour) {
|
|
|
249 |
|
|
|
250 |
// CommandeF
|
|
|
251 |
if (qteMvt > 0) {
|
|
|
252 |
qteNvlleEnAttenteRecept += qteMvt;
|
|
|
253 |
} else {
|
|
|
254 |
// CommanceC
|
|
|
255 |
qteNvlleEnAttenteExp -= qteMvt;
|
|
|
256 |
}
|
83 |
ilm |
257 |
}
|
73 |
ilm |
258 |
}
|
83 |
ilm |
259 |
rowVals.put("QTE_TH", qteNvlle);
|
|
|
260 |
rowVals.put("QTE_RECEPT_ATTENTE", qteNvlleEnAttenteRecept);
|
|
|
261 |
rowVals.put("QTE_LIV_ATTENTE", qteNvlleEnAttenteExp);
|
|
|
262 |
try {
|
156 |
ilm |
263 |
rowVals.update(rowStock.getID());
|
83 |
ilm |
264 |
} catch (SQLException e) {
|
156 |
ilm |
265 |
throw new SQLException("Erreur lors de la mise à jour du stock pour l'article " + rowArticle.getString("CODE"), e);
|
83 |
ilm |
266 |
}
|
19 |
ilm |
267 |
}
|
73 |
ilm |
268 |
|
18 |
ilm |
269 |
}
|
19 |
ilm |
270 |
return map;
|
18 |
ilm |
271 |
}
|
|
|
272 |
|
83 |
ilm |
273 |
public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise) {
|
174 |
ilm |
274 |
createCommandeF(col, rowDevise, "");
|
67 |
ilm |
275 |
}
|
19 |
ilm |
276 |
|
174 |
ilm |
277 |
public static void createCommandeF(final ListMap<SQLRow, SQLRowValues> col, final SQLRow rowDevise, final String ref) {
|
73 |
ilm |
278 |
if (SwingUtilities.isEventDispatchThread()) {
|
|
|
279 |
throw new IllegalStateException("This method must be called outside of EDT");
|
|
|
280 |
}
|
83 |
ilm |
281 |
if (col.size() > 0) {
|
19 |
ilm |
282 |
|
73 |
ilm |
283 |
final SQLElement commande = Configuration.getInstance().getDirectory().getElement("COMMANDE");
|
174 |
ilm |
284 |
Boolean useCommandeEnCours = SQLPreferences.getMemCached(commande.getTable().getDBRoot()).getBoolean(GestionCommercialeGlobalPreferencePanel.COMMANDE_FOURNISSEUR_EN_COURS, false);
|
83 |
ilm |
285 |
for (final Entry<SQLRow, List<SQLRowValues>> e : col.entrySet()) {
|
|
|
286 |
final SQLRow fournisseur = e.getKey();
|
73 |
ilm |
287 |
// On regarde si il existe une commande en cours existante
|
|
|
288 |
final SQLSelect sel = new SQLSelect();
|
|
|
289 |
sel.addSelectStar(commande.getTable());
|
|
|
290 |
Where w = new Where(commande.getTable().getField("EN_COURS"), "=", Boolean.TRUE);
|
|
|
291 |
w = w.and(new Where(commande.getTable().getField("ID_FOURNISSEUR"), "=", fournisseur.getID()));
|
|
|
292 |
sel.setWhere(w);
|
19 |
ilm |
293 |
|
142 |
ilm |
294 |
final List<SQLRow> rowsCmd = !useCommandeEnCours ? null
|
|
|
295 |
: (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel));
|
19 |
ilm |
296 |
|
73 |
ilm |
297 |
SwingUtilities.invokeLater(new Runnable() {
|
|
|
298 |
|
|
|
299 |
@Override
|
|
|
300 |
public void run() {
|
19 |
ilm |
301 |
SQLRow commandeExistante = null;
|
|
|
302 |
if (rowsCmd != null && rowsCmd.size() > 0) {
|
|
|
303 |
commandeExistante = rowsCmd.get(0);
|
|
|
304 |
}
|
|
|
305 |
EditFrame frame;
|
|
|
306 |
CommandeSQLComponent cmp;
|
|
|
307 |
|
|
|
308 |
if (commandeExistante != null) {
|
|
|
309 |
frame = new EditFrame(commande, EditMode.MODIFICATION);
|
|
|
310 |
cmp = (CommandeSQLComponent) frame.getSQLComponent();
|
|
|
311 |
cmp.select(commandeExistante);
|
|
|
312 |
} else {
|
|
|
313 |
frame = new EditFrame(commande);
|
|
|
314 |
cmp = (CommandeSQLComponent) frame.getSQLComponent();
|
41 |
ilm |
315 |
final SQLRowValues rowVals = new SQLRowValues(commande.getTable());
|
|
|
316 |
final SQLElement eltComm = Configuration.getInstance().getDirectory().getElement("COMMERCIAL");
|
19 |
ilm |
317 |
int idUser = UserManager.getInstance().getCurrentUser().getId();
|
|
|
318 |
SQLRow rowsComm = SQLBackgroundTableCache.getInstance().getCacheForTable(eltComm.getTable()).getFirstRowContains(idUser, eltComm.getTable().getField("ID_USER_COMMON"));
|
|
|
319 |
|
|
|
320 |
if (rowsComm != null) {
|
|
|
321 |
rowVals.put("ID_COMMERCIAL", rowsComm.getID());
|
|
|
322 |
}
|
132 |
ilm |
323 |
if (fournisseur != null && !fournisseur.isUndefined()) {
|
|
|
324 |
rowVals.put("ID_FOURNISSEUR", fournisseur.getID());
|
|
|
325 |
}
|
19 |
ilm |
326 |
if (rowDevise != null) {
|
|
|
327 |
rowVals.put("ID_DEVISE", rowDevise.getID());
|
|
|
328 |
}
|
67 |
ilm |
329 |
if (commande.getTable().contains("ID_ADRESSE")) {
|
|
|
330 |
rowVals.put("ID_ADRESSE", null);
|
|
|
331 |
}
|
|
|
332 |
rowVals.put("NOM", ref);
|
19 |
ilm |
333 |
cmp.select(rowVals);
|
73 |
ilm |
334 |
cmp.getRowValuesTable().getRowValuesTableModel().clearRows();
|
19 |
ilm |
335 |
}
|
|
|
336 |
|
156 |
ilm |
337 |
CommandeItemTable itemTable = cmp.getRowValuesTablePanel();
|
|
|
338 |
|
73 |
ilm |
339 |
final RowValuesTableModel model = cmp.getRowValuesTable().getRowValuesTableModel();
|
185 |
ilm |
340 |
final List<SQLRowValues> articleToCmd = e.getValue();
|
|
|
341 |
// Tri des items par code, couleur et taille
|
|
|
342 |
Collections.sort(articleToCmd, new Comparator<SQLRowValues>() {
|
|
|
343 |
@Override
|
|
|
344 |
public int compare(SQLRowValues o1, SQLRowValues o2) {
|
|
|
345 |
SQLRowAccessor o1ArticleNumber = o1.contains("ID_ARTICLE") ? o1.getNonEmptyForeign("ID_ARTICLE") : null;
|
|
|
346 |
SQLRowAccessor o2ArticleNumber = o1.contains("ID_ARTICLE") ? o1.getNonEmptyForeign("ID_ARTICLE") : null;
|
|
|
347 |
if (o1ArticleNumber != null && o2ArticleNumber != null) {
|
|
|
348 |
int comparedCode = o1ArticleNumber.getString("CODE").compareTo(o1ArticleNumber.getString("CODE"));
|
|
|
349 |
if (comparedCode == 0) {
|
|
|
350 |
SQLRowAccessor o1CouleurNumber = o1ArticleNumber.contains("ID_ARTICLE_DECLINAISON_COULEUR")
|
|
|
351 |
? o1ArticleNumber.getNonEmptyForeign("ID_ARTICLE_DECLINAISON_COULEUR")
|
|
|
352 |
: null;
|
|
|
353 |
SQLRowAccessor o2CouleurNumber = o2ArticleNumber.contains("ID_ARTICLE_DECLINAISON_COULEUR")
|
|
|
354 |
? o2ArticleNumber.getNonEmptyForeign("ID_ARTICLE_DECLINAISON_COULEUR")
|
|
|
355 |
: null;
|
|
|
356 |
if (o1CouleurNumber != null && o2CouleurNumber != null) {
|
|
|
357 |
int comparedCouleurCode = o1CouleurNumber.getBigDecimal("ORDRE").compareTo(o2CouleurNumber.getBigDecimal("ORDRE"));
|
|
|
358 |
if (comparedCouleurCode != 0) {
|
|
|
359 |
return comparedCouleurCode;
|
|
|
360 |
}
|
|
|
361 |
}
|
|
|
362 |
SQLRowAccessor o1TailleNumber = o1ArticleNumber.contains("ID_ARTICLE_TAILLE_COULEUR") ? o1ArticleNumber.getNonEmptyForeign("ID_ARTICLE_TAILLE_COULEUR") : null;
|
|
|
363 |
SQLRowAccessor o2TailleNumber = o2ArticleNumber.contains("ID_ARTICLE_TAILLE_COULEUR") ? o2ArticleNumber.getNonEmptyForeign("ID_ARTICLE_TAILLE_COULEUR") : null;
|
|
|
364 |
if (o1TailleNumber != null && o2TailleNumber != null) {
|
|
|
365 |
int comparedTailleCode = o1TailleNumber.getBigDecimal("ORDRE").compareTo(o2TailleNumber.getBigDecimal("ORDRE"));
|
|
|
366 |
return comparedTailleCode;
|
|
|
367 |
}
|
|
|
368 |
}
|
|
|
369 |
return comparedCode;
|
|
|
370 |
} else {
|
|
|
371 |
return o1.getString("CODE").compareTo(o2.getString("CODE"));
|
|
|
372 |
}
|
|
|
373 |
}
|
|
|
374 |
});
|
|
|
375 |
for (SQLRowValues rowValsElt : articleToCmd) {
|
19 |
ilm |
376 |
SQLRowValues rowValsMatch = null;
|
|
|
377 |
int index = 0;
|
|
|
378 |
for (int i = 0; i < model.getRowCount(); i++) {
|
41 |
ilm |
379 |
final SQLRowValues rowValsCmdElt = model.getRowValuesAt(i);
|
182 |
ilm |
380 |
Number lineArticleNumber = rowValsCmdElt.contains("ID_ARTICLE") ? rowValsCmdElt.getNonEmptyForeignIDNumber("ID_ARTICLE") : null;
|
|
|
381 |
Number lineToAddArticleNumber = rowValsElt.contains("ID_ARTICLE") ? rowValsElt.getNonEmptyForeignIDNumber("ID_ARTICLE") : null;
|
|
|
382 |
if (lineToAddArticleNumber == null || lineArticleNumber == null || lineArticleNumber.equals(lineToAddArticleNumber)) {
|
|
|
383 |
if (ReferenceArticleSQLElement.isReferenceEquals(rowValsCmdElt, rowValsElt)) {
|
|
|
384 |
rowValsMatch = rowValsCmdElt;
|
|
|
385 |
index = i;
|
|
|
386 |
break;
|
|
|
387 |
}
|
19 |
ilm |
388 |
}
|
|
|
389 |
}
|
|
|
390 |
if (rowValsMatch != null) {
|
174 |
ilm |
391 |
|
|
|
392 |
int qte = rowValsMatch.getInt("QTE");
|
|
|
393 |
BigDecimal qteUV = rowValsMatch.getBigDecimal("QTE_UNITAIRE");
|
|
|
394 |
|
|
|
395 |
if (rowValsMatch.getObject("ID_UNITE_VENTE") != null && rowValsMatch.getForeignID("ID_UNITE_VENTE") != UniteVenteArticleSQLElement.A_LA_PIECE) {
|
|
|
396 |
qteUV = qteUV.multiply(new BigDecimal(qte));
|
|
|
397 |
int qteElt = rowValsElt.getInt("QTE");
|
|
|
398 |
BigDecimal qteUVElt = rowValsElt.getBigDecimal("QTE_UNITAIRE");
|
|
|
399 |
qteUV = qteUV.add(qteUVElt.multiply(new BigDecimal(qteElt)));
|
|
|
400 |
qte = 1;
|
|
|
401 |
} else {
|
|
|
402 |
qte += rowValsElt.getInt("QTE");
|
|
|
403 |
}
|
|
|
404 |
|
|
|
405 |
model.putValue(qte, index, "QTE");
|
|
|
406 |
model.putValue(qteUV, index, "QTE_UNITAIRE");
|
19 |
ilm |
407 |
} else {
|
|
|
408 |
model.addRow(rowValsElt);
|
156 |
ilm |
409 |
if (rowValsElt.getObject("ID_ARTICLE") != null && !rowValsElt.isForeignEmpty("ID_ARTICLE")) {
|
|
|
410 |
Object o = itemTable.tarifCompletion(rowValsElt.getForeign("ID_ARTICLE").asRow(), "PRIX_METRIQUE_HA_1");
|
|
|
411 |
if (o != null) {
|
|
|
412 |
model.putValue(o, model.getRowCount() - 1, "PRIX_METRIQUE_HA_1");
|
|
|
413 |
}
|
|
|
414 |
}
|
19 |
ilm |
415 |
}
|
|
|
416 |
}
|
|
|
417 |
|
|
|
418 |
frame.pack();
|
73 |
ilm |
419 |
FrameUtil.show(frame);
|
|
|
420 |
|
19 |
ilm |
421 |
}
|
73 |
ilm |
422 |
});
|
|
|
423 |
}
|
174 |
ilm |
424 |
} else {
|
|
|
425 |
SwingUtilities.invokeLater(new Runnable() {
|
73 |
ilm |
426 |
|
174 |
ilm |
427 |
@Override
|
|
|
428 |
public void run() {
|
|
|
429 |
JOptionPane.showMessageDialog(null, "Aucune commande à passer", "Commande fournisseur", JOptionPane.INFORMATION_MESSAGE);
|
|
|
430 |
}
|
|
|
431 |
|
|
|
432 |
});
|
19 |
ilm |
433 |
}
|
|
|
434 |
|
|
|
435 |
}
|
|
|
436 |
|
132 |
ilm |
437 |
@Override
|
|
|
438 |
protected void _initListRequest(ListSQLRequest req) {
|
|
|
439 |
super._initListRequest(req);
|
|
|
440 |
req.addToGraphToFetch("SOURCE", "IDSOURCE");
|
|
|
441 |
}
|
|
|
442 |
|
73 |
ilm |
443 |
public static final void showSource(final int id) {
|
|
|
444 |
if (!SwingUtilities.isEventDispatchThread()) {
|
|
|
445 |
throw new IllegalStateException("This method must be called from EDT");
|
|
|
446 |
}
|
18 |
ilm |
447 |
if (id != 1) {
|
73 |
ilm |
448 |
final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
|
|
|
449 |
final SQLTable tableMvt = base.getTable("MOUVEMENT_STOCK");
|
|
|
450 |
final String stringTableSource = tableMvt.getRow(id).getString("SOURCE");
|
|
|
451 |
SwingUtilities.invokeLater(new Runnable() {
|
|
|
452 |
public void run() {
|
|
|
453 |
|
|
|
454 |
final EditFrame f;
|
|
|
455 |
// Si une source est associée on l'affiche en readonly
|
|
|
456 |
if (stringTableSource.trim().length() != 0 && tableMvt.getRow(id).getInt("IDSOURCE") != 1) {
|
|
|
457 |
f = new EditFrame(Configuration.getInstance().getDirectory().getElement(stringTableSource), EditPanel.READONLY);
|
|
|
458 |
f.selectionId(tableMvt.getRow(id).getInt("IDSOURCE"));
|
|
|
459 |
} else {
|
|
|
460 |
// Sinon on affiche le mouvement de stock
|
|
|
461 |
f = new EditFrame(Configuration.getInstance().getDirectory().getElement(tableMvt), EditPanel.READONLY);
|
|
|
462 |
f.selectionId(id);
|
|
|
463 |
}
|
|
|
464 |
f.pack();
|
|
|
465 |
FrameUtil.show(f);
|
|
|
466 |
|
|
|
467 |
}
|
|
|
468 |
});
|
18 |
ilm |
469 |
} else {
|
|
|
470 |
System.err.println("Aucun mouvement associé, impossible de modifier ou d'accéder à la source de cette ecriture!");
|
|
|
471 |
}
|
|
|
472 |
}
|
57 |
ilm |
473 |
|
182 |
ilm |
474 |
public void transfertStock(BigDecimal qteReel, final Date dateValue, final SQLRow selectedRowArticle, final SQLRow selectedRowDepotDepart, final SQLRow selectedRowDepotArrivee,
|
|
|
475 |
final String labelTrStock) {
|
|
|
476 |
final boolean usePrice = getTable().contains("PRICE");
|
|
|
477 |
try {
|
|
|
478 |
SQLUtils.executeAtomic(selectedRowDepotDepart.getTable().getDBSystemRoot().getDataSource(), new ConnectionHandlerNoSetup<Object, SQLException>() {
|
|
|
479 |
@Override
|
|
|
480 |
public Object handle(SQLDataSource ds) throws SQLException {
|
|
|
481 |
List<StockItem> stockItems = new ArrayList<StockItem>();
|
|
|
482 |
List<String> multipleRequestsHundred = new ArrayList<String>(100);
|
|
|
483 |
{
|
|
|
484 |
// DEPART
|
|
|
485 |
final SQLRowAccessor rowStockDepart = ProductComponent.findOrCreateStock(selectedRowArticle, selectedRowDepotDepart);
|
|
|
486 |
StockItem item = new StockItem(selectedRowArticle, rowStockDepart);
|
|
|
487 |
if (!item.isStockInit()) {
|
|
|
488 |
SQLRowValues rowVals = new SQLRowValues(getTable().getTable("STOCK"));
|
|
|
489 |
rowVals.put("ID_ARTICLE", selectedRowArticle.getID());
|
|
|
490 |
rowVals.put("ID_DEPOT_STOCK", selectedRowDepotDepart.getID());
|
|
|
491 |
rowVals.commit();
|
|
|
492 |
selectedRowArticle.fetchValues();
|
|
|
493 |
item = new StockItem(selectedRowArticle, rowStockDepart);
|
|
|
494 |
}
|
|
|
495 |
stockItems.add(item);
|
|
|
496 |
double diff = -qteReel.doubleValue();
|
|
|
497 |
item.updateQty(diff, TypeStockMouvement.REEL);
|
|
|
498 |
multipleRequestsHundred.add(getMvtRequest(dateValue, BigDecimal.ZERO, diff, item, getLabel(labelTrStock, selectedRowDepotDepart, selectedRowDepotArrivee), true, usePrice));
|
|
|
499 |
item.updateQty(diff, TypeStockMouvement.THEORIQUE);
|
|
|
500 |
multipleRequestsHundred.add(getMvtRequest(dateValue, BigDecimal.ZERO, diff, item, getLabel(labelTrStock, selectedRowDepotDepart, selectedRowDepotArrivee), false, usePrice));
|
|
|
501 |
multipleRequestsHundred.add(item.getUpdateRequest());
|
|
|
502 |
}
|
|
|
503 |
// ARRIVEE
|
|
|
504 |
{
|
|
|
505 |
final SQLRowAccessor rowStockArrivee = ProductComponent.findOrCreateStock(selectedRowArticle, selectedRowDepotArrivee);
|
|
|
506 |
StockItem item = new StockItem(selectedRowArticle, rowStockArrivee);
|
|
|
507 |
if (!item.isStockInit()) {
|
|
|
508 |
SQLRowValues rowVals = new SQLRowValues(getTable().getTable("STOCK"));
|
|
|
509 |
rowVals.put("ID_ARTICLE", selectedRowArticle.getID());
|
|
|
510 |
rowVals.put("ID_DEPOT_STOCK", selectedRowDepotArrivee.getID());
|
|
|
511 |
rowVals.commit();
|
|
|
512 |
selectedRowArticle.fetchValues();
|
|
|
513 |
item = new StockItem(selectedRowArticle, rowStockArrivee);
|
|
|
514 |
}
|
|
|
515 |
stockItems.add(item);
|
|
|
516 |
double diff = qteReel.doubleValue();
|
|
|
517 |
item.updateQty(diff, TypeStockMouvement.REEL);
|
|
|
518 |
multipleRequestsHundred.add(getMvtRequest(dateValue, BigDecimal.ZERO, diff, item, getLabel(labelTrStock, selectedRowDepotDepart, selectedRowDepotArrivee), true, usePrice));
|
|
|
519 |
item.updateQty(diff, TypeStockMouvement.THEORIQUE);
|
|
|
520 |
multipleRequestsHundred.add(getMvtRequest(dateValue, BigDecimal.ZERO, diff, item, getLabel(labelTrStock, selectedRowDepotDepart, selectedRowDepotArrivee), false, usePrice));
|
|
|
521 |
multipleRequestsHundred.add(item.getUpdateRequest());
|
|
|
522 |
}
|
|
|
523 |
|
|
|
524 |
final int size = multipleRequestsHundred.size();
|
|
|
525 |
List<? extends ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(size);
|
|
|
526 |
for (int i = 0; i < size; i++) {
|
|
|
527 |
handlers.add(null);
|
|
|
528 |
}
|
|
|
529 |
SQLUtils.executeMultiple(selectedRowArticle.getTable().getDBSystemRoot(), multipleRequestsHundred, handlers);
|
|
|
530 |
|
|
|
531 |
final DBRoot root = getTable().getDBRoot();
|
|
|
532 |
if (root.contains("ARTICLE_ELEMENT")) {
|
|
|
533 |
// Mise à jour des stocks des nomenclatures
|
|
|
534 |
ComposedItemStockUpdater comp = new ComposedItemStockUpdater(root, stockItems);
|
|
|
535 |
comp.update();
|
|
|
536 |
}
|
|
|
537 |
return null;
|
|
|
538 |
}
|
|
|
539 |
});
|
|
|
540 |
} catch (SQLException e1) {
|
|
|
541 |
ExceptionHandler.handle("Stock update error", e1);
|
|
|
542 |
}
|
|
|
543 |
}
|
|
|
544 |
|
|
|
545 |
private String getLabel(String label, SQLRowAccessor fromDepot, SQLRowAccessor toDepot) {
|
|
|
546 |
return label + " de " + fromDepot.getString("NOM") + " vers " + toDepot.getString("NOM");
|
|
|
547 |
}
|
|
|
548 |
|
|
|
549 |
private String getMvtRequest(Date time, BigDecimal prc, double qteFinal, StockItem item, String label, boolean reel, boolean usePrice) {
|
|
|
550 |
String mvtStockTableQuoted = getTable().getSQLName().quote();
|
|
|
551 |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
552 |
String mvtStockQuery = "INSERT INTO " + mvtStockTableQuoted + " (\"QTE\",\"DATE\",\"ID_ARTICLE\",\"ID_STOCK\",\"NOM\",\"REEL\",\"ORDRE\"";
|
|
|
553 |
|
|
|
554 |
if (usePrice && prc != null) {
|
|
|
555 |
mvtStockQuery += ",\"PRICE\"";
|
|
|
556 |
}
|
|
|
557 |
|
|
|
558 |
mvtStockQuery += ") VALUES(" + qteFinal + ",'" + dateFormat.format(time) + "'," + item.getArticle().getID() + "," + item.stock.getID() + ",'" + label + "'," + reel
|
|
|
559 |
+ ", (SELECT (MAX(\"ORDRE\")+1) FROM " + mvtStockTableQuoted + ")";
|
|
|
560 |
if (usePrice && prc != null) {
|
|
|
561 |
mvtStockQuery += "," + prc.setScale(6, RoundingMode.HALF_UP).toString();
|
|
|
562 |
}
|
|
|
563 |
mvtStockQuery += ")";
|
|
|
564 |
return mvtStockQuery;
|
|
|
565 |
}
|
|
|
566 |
|
57 |
ilm |
567 |
@Override
|
|
|
568 |
protected String createCode() {
|
156 |
ilm |
569 |
return createCodeOfPackage() + ".transaction";
|
57 |
ilm |
570 |
}
|
18 |
ilm |
571 |
}
|