21 |
ilm |
1 |
/*
|
|
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
|
|
3 |
*
|
|
|
4 |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
|
|
|
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.utils.correct;
|
|
|
15 |
|
83 |
ilm |
16 |
import org.openconcerto.erp.config.Log;
|
21 |
ilm |
17 |
import org.openconcerto.sql.changer.Changer;
|
|
|
18 |
import org.openconcerto.sql.model.DBRoot;
|
|
|
19 |
import org.openconcerto.sql.model.DBSystemRoot;
|
|
|
20 |
import org.openconcerto.sql.model.SQLBase;
|
|
|
21 |
import org.openconcerto.sql.model.SQLField;
|
|
|
22 |
import org.openconcerto.sql.model.SQLSelect;
|
|
|
23 |
import org.openconcerto.sql.model.SQLSelect.ArchiveMode;
|
|
|
24 |
import org.openconcerto.sql.model.SQLSystem;
|
|
|
25 |
import org.openconcerto.sql.model.SQLTable;
|
|
|
26 |
import org.openconcerto.sql.model.Where;
|
|
|
27 |
import org.openconcerto.sql.request.UpdateBuilder;
|
|
|
28 |
|
|
|
29 |
import java.sql.SQLException;
|
|
|
30 |
import java.util.Arrays;
|
|
|
31 |
import java.util.List;
|
|
|
32 |
|
|
|
33 |
/**
|
|
|
34 |
* Unarchive ECRITURE to balance MOUVEMENT, then link SAISIE_KM_ELEMENT and a unique matching
|
|
|
35 |
* ECRITURE.
|
|
|
36 |
*
|
|
|
37 |
* @author Sylvain CUAZ
|
|
|
38 |
*/
|
|
|
39 |
public class CorrectMouvement extends Changer<DBRoot> {
|
|
|
40 |
|
80 |
ilm |
41 |
static public final SQLSelect createUnbalancedSelect(final DBRoot societeRoot) {
|
|
|
42 |
return createUnbalancedSelect(societeRoot.getTable("ECRITURE").getField("ID_MOUVEMENT"));
|
|
|
43 |
}
|
|
|
44 |
|
|
|
45 |
static private final SQLSelect createUnbalancedSelect(final SQLField ecritureMvtFF) {
|
|
|
46 |
final SQLTable ecritureT = ecritureMvtFF.getTable();
|
|
|
47 |
|
|
|
48 |
final SQLSelect selUnbalanced = new SQLSelect();
|
|
|
49 |
selUnbalanced.addSelect(ecritureMvtFF);
|
|
|
50 |
selUnbalanced.addGroupBy(ecritureMvtFF);
|
|
|
51 |
selUnbalanced.setHaving(Where.quote(ecritureT.getBase().quote("SUM(%n) != SUM(%n)", ecritureT.getField("DEBIT"), ecritureT.getField("CREDIT"))));
|
|
|
52 |
return selUnbalanced;
|
|
|
53 |
}
|
|
|
54 |
|
21 |
ilm |
55 |
public CorrectMouvement(DBSystemRoot b) {
|
|
|
56 |
super(b);
|
|
|
57 |
}
|
|
|
58 |
|
|
|
59 |
@Override
|
|
|
60 |
protected void changeImpl(DBRoot societeRoot) throws SQLException {
|
|
|
61 |
final SQLTable ecritureT = societeRoot.getTable("ECRITURE");
|
|
|
62 |
|
|
|
63 |
// some ECRITURE were ARCHIVED creating unbalanced MOUVEMENT
|
|
|
64 |
// find MOUVEMENT that would be balanced if we unarchived all of its ECRITURE
|
|
|
65 |
{
|
|
|
66 |
final SQLField ecritureMvtFF = ecritureT.getField("ID_MOUVEMENT");
|
80 |
ilm |
67 |
final SQLSelect selUnbalanced = createUnbalancedSelect(ecritureMvtFF);
|
21 |
ilm |
68 |
|
|
|
69 |
final SQLSelect selUnfixable = new SQLSelect(selUnbalanced);
|
|
|
70 |
selUnfixable.setArchivedPolicy(ArchiveMode.BOTH);
|
|
|
71 |
|
|
|
72 |
final String selFixableUnbalanced = "( " + selUnbalanced.asString() + "\nEXCEPT\n" + selUnfixable.asString() + " )";
|
|
|
73 |
|
|
|
74 |
final UpdateBuilder updateUnbalanced = new UpdateBuilder(ecritureT);
|
83 |
ilm |
75 |
updateUnbalanced.addVirtualJoin(selFixableUnbalanced, "semiArchivedMvt", false, ecritureMvtFF.getName(), ecritureMvtFF.getName());
|
21 |
ilm |
76 |
updateUnbalanced.set(ecritureT.getArchiveField().getName(), "0");
|
|
|
77 |
|
|
|
78 |
getDS().execute(updateUnbalanced.asString());
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
// match SAISIE_KM_ELEMENT with their lost ECRITURE
|
83 |
ilm |
82 |
if (getSyntax().getSystem() == SQLSystem.H2) {
|
|
|
83 |
Log.get().warning("Matching SAISIE_KM_ELEMENT with their lost ECRITURE unsupported");
|
|
|
84 |
} else {
|
21 |
ilm |
85 |
final SQLTable saisieKmElemT = societeRoot.getGraph().findReferentTable(ecritureT, "SAISIE_KM_ELEMENT");
|
|
|
86 |
final SQLTable saisieKmT = saisieKmElemT.getForeignTable("ID_SAISIE_KM");
|
|
|
87 |
// select ECRITURE which can be identified in a MOUVEMENT by its CREDIT/DEBIT and isn't
|
|
|
88 |
// already linked to a SAISIE_KM_ELEMENT
|
80 |
ilm |
89 |
final SQLSelect selIdentifiableNonUsed = new SQLSelect();
|
21 |
ilm |
90 |
final List<String> uniqueFields = Arrays.asList("ID_MOUVEMENT", "DEBIT", "CREDIT");
|
|
|
91 |
selIdentifiableNonUsed.addAllSelect(ecritureT, uniqueFields);
|
|
|
92 |
final String quotedID = ecritureT.getKey().getSQLName(ecritureT).quote();
|
|
|
93 |
final String uniqueID;
|
|
|
94 |
if (getSyntax().getSystem() == SQLSystem.POSTGRESQL)
|
|
|
95 |
uniqueID = "(array_agg(" + quotedID + "))[1]";
|
|
|
96 |
else
|
|
|
97 |
uniqueID = "cast(GROUP_CONCAT(" + quotedID + ") as integer)";
|
|
|
98 |
final String uniqueIDAlias = "ID";
|
|
|
99 |
selIdentifiableNonUsed.addRawSelect(uniqueID, uniqueIDAlias);
|
|
|
100 |
selIdentifiableNonUsed.addBackwardJoin("LEFT", null, saisieKmElemT.getField("ID_ECRITURE"), null);
|
|
|
101 |
// unused
|
|
|
102 |
selIdentifiableNonUsed.setWhere(Where.isNull(saisieKmElemT.getKey()));
|
|
|
103 |
// identifiable
|
|
|
104 |
for (final String uniqField : uniqueFields)
|
|
|
105 |
selIdentifiableNonUsed.addGroupBy(ecritureT.getField(uniqField));
|
|
|
106 |
selIdentifiableNonUsed.setHaving(Where.createRaw("count(*) = 1"));
|
|
|
107 |
|
|
|
108 |
final UpdateBuilder update = new UpdateBuilder(saisieKmElemT);
|
83 |
ilm |
109 |
update.addForwardVirtualJoin(saisieKmT, "ID_SAISIE_KM");
|
65 |
ilm |
110 |
update.addRawTable("( " + selIdentifiableNonUsed.asString() + " )", "e");
|
21 |
ilm |
111 |
|
|
|
112 |
Where joinEcritureW = null;
|
|
|
113 |
for (final String uniqField : uniqueFields) {
|
|
|
114 |
final SQLTable t = uniqField.equals("ID_MOUVEMENT") ? saisieKmT : saisieKmElemT;
|
|
|
115 |
joinEcritureW = Where.quote("e." + SQLBase.quoteIdentifier(uniqField) + "= %f", t.getField(uniqField)).and(joinEcritureW);
|
|
|
116 |
}
|
|
|
117 |
final Where dontOverwrite = new Where(saisieKmElemT.getField("ID_ECRITURE"), Where.NULL_IS_DATA_EQ, ecritureT.getUndefinedIDNumber());
|
|
|
118 |
final Where dontUpdateUndef = new Where(saisieKmElemT.getKey(), Where.NULL_IS_DATA_NEQ, saisieKmElemT.getUndefinedIDNumber());
|
|
|
119 |
final Where unarchived = new Where(saisieKmElemT.getArchiveField(), "=", 0);
|
83 |
ilm |
120 |
update.setWhere(joinEcritureW.and(dontOverwrite).and(dontUpdateUndef).and(unarchived));
|
21 |
ilm |
121 |
|
|
|
122 |
update.set("ID_ECRITURE", "e." + SQLBase.quoteIdentifier(uniqueIDAlias));
|
|
|
123 |
|
|
|
124 |
getDS().execute(update.asString());
|
|
|
125 |
}
|
|
|
126 |
}
|
|
|
127 |
}
|