OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 65 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
 
16
import org.openconcerto.sql.changer.Changer;
17
import org.openconcerto.sql.model.DBRoot;
18
import org.openconcerto.sql.model.DBSystemRoot;
19
import org.openconcerto.sql.model.SQLBase;
20
import org.openconcerto.sql.model.SQLField;
21
import org.openconcerto.sql.model.SQLName;
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
 
41
    public CorrectMouvement(DBSystemRoot b) {
42
        super(b);
43
    }
44
 
45
    @Override
46
    protected void changeImpl(DBRoot societeRoot) throws SQLException {
47
        final SQLTable ecritureT = societeRoot.getTable("ECRITURE");
48
 
49
        // some ECRITURE were ARCHIVED creating unbalanced MOUVEMENT
50
        // find MOUVEMENT that would be balanced if we unarchived all of its ECRITURE
51
        {
52
            final SQLField ecritureMvtFF = ecritureT.getField("ID_MOUVEMENT");
53
            final SQLSelect selUnbalanced = new SQLSelect(societeRoot.getBase());
54
            selUnbalanced.addSelect(ecritureMvtFF);
55
            selUnbalanced.addGroupBy(ecritureMvtFF);
56
            selUnbalanced.setHaving(Where.quote(societeRoot.getBase().quote("SUM(%n) != SUM(%n)", ecritureT.getField("DEBIT"), ecritureT.getField("CREDIT"))));
57
 
58
            final SQLSelect selUnfixable = new SQLSelect(selUnbalanced);
59
            selUnfixable.setArchivedPolicy(ArchiveMode.BOTH);
60
 
61
            final String selFixableUnbalanced = "( " + selUnbalanced.asString() + "\nEXCEPT\n" + selUnfixable.asString() + " )";
62
 
63
            final UpdateBuilder updateUnbalanced = new UpdateBuilder(ecritureT);
64
            updateUnbalanced.addTable(selFixableUnbalanced, SQLBase.quoteIdentifier("semiArchivedMvt"));
65
            updateUnbalanced.setWhere(Where.quote("%i = %f", new SQLName("semiArchivedMvt", "ID_MOUVEMENT"), ecritureMvtFF));
66
            updateUnbalanced.set(ecritureT.getArchiveField().getName(), "0");
67
 
68
            getDS().execute(updateUnbalanced.asString());
69
        }
70
 
71
        // match SAISIE_KM_ELEMENT with their lost ECRITURE
72
        {
73
            final SQLTable saisieKmElemT = societeRoot.getGraph().findReferentTable(ecritureT, "SAISIE_KM_ELEMENT");
74
            final SQLTable saisieKmT = saisieKmElemT.getForeignTable("ID_SAISIE_KM");
75
            // select ECRITURE which can be identified in a MOUVEMENT by its CREDIT/DEBIT and isn't
76
            // already linked to a SAISIE_KM_ELEMENT
77
            final SQLSelect selIdentifiableNonUsed = new SQLSelect(societeRoot.getBase());
78
            final List<String> uniqueFields = Arrays.asList("ID_MOUVEMENT", "DEBIT", "CREDIT");
79
            selIdentifiableNonUsed.addAllSelect(ecritureT, uniqueFields);
80
            final String quotedID = ecritureT.getKey().getSQLName(ecritureT).quote();
81
            final String uniqueID;
82
            if (getSyntax().getSystem() == SQLSystem.POSTGRESQL)
83
                uniqueID = "(array_agg(" + quotedID + "))[1]";
84
            else
85
                uniqueID = "cast(GROUP_CONCAT(" + quotedID + ") as integer)";
86
            final String uniqueIDAlias = "ID";
87
            selIdentifiableNonUsed.addRawSelect(uniqueID, uniqueIDAlias);
88
            selIdentifiableNonUsed.addBackwardJoin("LEFT", null, saisieKmElemT.getField("ID_ECRITURE"), null);
89
            // unused
90
            selIdentifiableNonUsed.setWhere(Where.isNull(saisieKmElemT.getKey()));
91
            // identifiable
92
            for (final String uniqField : uniqueFields)
93
                selIdentifiableNonUsed.addGroupBy(ecritureT.getField(uniqField));
94
            selIdentifiableNonUsed.setHaving(Where.createRaw("count(*) = 1"));
95
 
96
            final UpdateBuilder update = new UpdateBuilder(saisieKmElemT);
97
            update.addTable(saisieKmT.getSQLName().quote(), null);
98
            update.addTable("( " + selIdentifiableNonUsed.asString() + " )", "e");
99
 
100
            final Where joinSaisieKmW = new Where(saisieKmElemT.getField("ID_SAISIE_KM"), "=", saisieKmT.getKey());
101
            Where joinEcritureW = null;
102
            for (final String uniqField : uniqueFields) {
103
                final SQLTable t = uniqField.equals("ID_MOUVEMENT") ? saisieKmT : saisieKmElemT;
104
                joinEcritureW = Where.quote("e." + SQLBase.quoteIdentifier(uniqField) + "= %f", t.getField(uniqField)).and(joinEcritureW);
105
            }
106
            final Where dontOverwrite = new Where(saisieKmElemT.getField("ID_ECRITURE"), Where.NULL_IS_DATA_EQ, ecritureT.getUndefinedIDNumber());
107
            final Where dontUpdateUndef = new Where(saisieKmElemT.getKey(), Where.NULL_IS_DATA_NEQ, saisieKmElemT.getUndefinedIDNumber());
108
            final Where unarchived = new Where(saisieKmElemT.getArchiveField(), "=", 0);
109
            update.setWhere(joinSaisieKmW.and(joinEcritureW).and(dontOverwrite).and(dontUpdateUndef).and(unarchived));
110
 
111
            update.set("ID_ECRITURE", "e." + SQLBase.quoteIdentifier(uniqueIDAlias));
112
 
113
            getDS().execute(update.asString());
114
        }
115
    }
116
}