OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 141 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
112 ilm 1
package org.openconcerto.modules.operation;
2
 
3
import java.beans.PropertyChangeEvent;
4
import java.beans.PropertyChangeListener;
5
import java.sql.ResultSet;
6
import java.sql.SQLException;
7
import java.util.ArrayList;
141 ilm 8
import java.util.Arrays;
112 ilm 9
import java.util.Date;
10
import java.util.HashSet;
11
import java.util.List;
12
import java.util.Set;
13
import java.util.UUID;
14
 
15
import javax.swing.JComponent;
16
 
17
import org.apache.commons.dbutils.ResultSetHandler;
18
import org.openconcerto.erp.config.ComptaPropsConfiguration;
19
import org.openconcerto.sql.PropsConfiguration;
20
import org.openconcerto.sql.element.GroupSQLComponent;
21
import org.openconcerto.sql.element.SQLElement;
22
import org.openconcerto.sql.model.DBRoot;
23
import org.openconcerto.sql.model.SQLBase;
24
import org.openconcerto.sql.model.SQLRow;
25
import org.openconcerto.sql.model.SQLRowAccessor;
141 ilm 26
import org.openconcerto.sql.model.SQLRowValues;
27
import org.openconcerto.sql.model.SQLSyntax;
28
import org.openconcerto.sql.model.SQLSystem;
112 ilm 29
import org.openconcerto.sql.model.SQLTable;
30
import org.openconcerto.sql.sqlobject.ElementComboBox;
31
import org.openconcerto.sql.sqlobject.SQLTextCombo;
32
import org.openconcerto.sql.utils.SQLUtils;
33
import org.openconcerto.ui.JLabelBold;
34
import org.openconcerto.ui.component.ITextArea;
35
import org.openconcerto.ui.date.DateRange;
36
import org.openconcerto.ui.date.DateRangePlannerPanel;
37
import org.openconcerto.utils.ExceptionHandler;
38
import org.openconcerto.utils.checks.ValidState;
39
 
40
public class MultiOperationSQLComponent extends GroupSQLComponent {
41
 
42
    private String uid;
43
    private Date dateStart;
44
 
45
    public MultiOperationSQLComponent(SQLElement element) {
46
        super(element, new MultiOperationGroup());
47
    }
48
 
49
    @Override
50
    public JComponent createEditor(String id) {
51
        if (id.equals("operation.description")) {
52
            return new ITextArea(15, 3);
53
        } else if (id.equals("operation.dates")) {
54
            final DateRangePlannerPanel dateRangePlannerPanel = new DateRangePlannerPanel();
55
            final PropertyChangeListener listener = new PropertyChangeListener() {
56
                @Override
57
                public void propertyChange(PropertyChangeEvent evt) {
58
                    fireValidChange();
59
                }
60
            };
61
            dateRangePlannerPanel.getJDateStart().addValueListener(listener);
62
            dateRangePlannerPanel.getJDateEnd().addValueListener(listener);
63
            return dateRangePlannerPanel;
64
        } else if (id.equals("operation.type") || id.equals("operation.status")) {
150 ilm 65
            return new SQLTextCombo() {
66
                @Override
67
                public boolean canComplete(String originalText) {
68
                    return originalText != null && !originalText.trim().isEmpty();
69
                }
70
            };
112 ilm 71
        }
72
        return super.createEditor(id);
73
    }
74
 
75
    @Override
76
    protected JComponent createLabel(String id) {
77
        if (id.equals("operation.dates")) {
78
            return new JLabelBold("");
79
        }
80
        return super.createLabel(id);
81
    }
82
 
83
    DateRangePlannerPanel getDateRangeTable() {
84
        return (DateRangePlannerPanel) getEditor("operation.dates");
85
    }
86
 
87
    @Override
88
    public void select(final SQLRowAccessor r) {
89
        super.select(r);
90
        if (r != null) {
91
            this.uid = r.getString("PLANNER_UID");
92
            final String xml = r.getString("PLANNER_XML");
93
            try {
94
                if (xml != null && !xml.isEmpty()) {
95
                    this.getDateRangeTable().configureFromXML(xml);
96
                }
97
            } catch (Exception e) {
98
                ExceptionHandler.handle("Cannot configure editor from:\n" + xml, e);
99
            }
100
        } else {
101
            this.uid = null;
102
        }
103
    }
104
 
105
    @Override
106
    public void update() {
107
 
108
        if (this.uid != null && !uid.isEmpty() && this.dateStart != null) {
109
            final OperationSQLElement elem = (OperationSQLElement) PropsConfiguration.getInstance().getDirectory().getElement(ModuleOperation.TABLE_OPERATION);
110
            try {
111
                elem.fastDelete(this.uid, this.dateStart);
112
                insert(null);
113
            } catch (Exception e) {
114
                ExceptionHandler.handle("Update error", e);
115
            }
116
        }
117
    }
118
 
119
    @Override
120
    public int insert(SQLRow order) {
121
 
122
        final List<DateRange> ranges = this.getDateRangeTable().getRanges();
123
        if (ranges.isEmpty()) {
124
            // Fill with current date to avoid issue... :(
125
            ranges.add(new DateRange(System.currentTimeMillis()));
126
        }
127
 
128
        // Split pour ne pas bloquer l'UI
129
        // Synchrone
130
        final List<DateRange> rangesPart1 = new ArrayList<DateRange>();
131
        // Asynchrone
132
        final List<DateRange> rangesPart2 = new ArrayList<DateRange>();
133
        for (int i = 0; i < ranges.size(); i++) {
134
            if (i < 10) {
135
                rangesPart1.add(ranges.get(i));
136
            } else {
137
                rangesPart2.add(ranges.get(i));
138
            }
139
 
140
        }
141
        final String type = ((SQLTextCombo) this.getEditor("operation.type")).getCurrentValue();
142
        final String siteName = ((ElementComboBox) this.getEditor("operation.site")).getSelectedRow().getString("NAME");
143
        //
144
        final String summary = siteName + " " + type;
145
        final String description = ((ITextArea) this.getEditor("operation.description")).getText();
146
        final String status = ((SQLTextCombo) this.getEditor("operation.status")).getCurrentValue();
147
 
148
        final int idSite = ((ElementComboBox) this.getEditor("operation.site")).getSelectedId();
149
        final int idUser = ((ElementComboBox) this.getEditor("operation.user")).getSelectedId();
150
 
151
        // Create Groups
152
        final List<Number> calendarGroupIds = multipleInsertCalendarGroups(rangesPart1.size(), summary, description);
153
        // Create Operations
154
        final String plannerUid = UUID.randomUUID().toString();
155
 
156
        final String plannerXML = getDateRangeTable().getConfigXML();
157
 
158
        final List<Number> operationsIds = multipleInsertOperation(calendarGroupIds, idSite, status, type, description, idUser, plannerUid, plannerXML);
159
 
160
        multipleInsertCalendarItems(calendarGroupIds, operationsIds, rangesPart1, summary, description, status);
161
 
162
        if (!rangesPart2.isEmpty()) {
163
            final Thread t = new Thread(new Runnable() {
164
 
165
                @Override
166
                public void run() {
167
                    // Create Groups
168
                    final List<Number> calendarGroupIds = multipleInsertCalendarGroups(rangesPart2.size(), summary, description);
169
                    // Create Operations
170
                    final List<Number> operationsIds = multipleInsertOperation(calendarGroupIds, idSite, status, type, description, idUser, plannerUid, plannerXML);
171
                    multipleInsertCalendarItems(calendarGroupIds, operationsIds, rangesPart2, summary, description, status);
172
                }
173
            });
174
            t.setName(this.toString());
175
            t.start();
176
        }
177
        ModuleOperation.reloadCalendars();
178
        return operationsIds.get(0).intValue();
179
    }
180
 
181
    private List<Number> multipleInsertCalendarGroups(int numberOfRowToCreate, String name, String description) {
182
        final List<Number> ids = new ArrayList<Number>();
183
        //
141 ilm 184
        SQLTable tCalendarItemGroup = getDirectory().getElement("CALENDAR_ITEM_GROUP").getTable();
185
        if (tCalendarItemGroup.getServer().getSQLSystem().equals(SQLSystem.POSTGRESQL)) {
186
            final SQLSyntax syntax = this.getTable().getDBSystemRoot().getSyntax();
187
            final List<String> fields = Arrays.asList("NAME", "DESCRIPTION", "ORDRE");
188
            final List<List<String>> values = new ArrayList<List<String>>(numberOfRowToCreate);
189
            for (int i = 0; i < numberOfRowToCreate; i++) {
190
                final List<String> row = new ArrayList<String>(fields.size());
191
                row.add(syntax.quoteString(name));
192
                row.add(syntax.quoteString(description));
193
                row.add("( select COALESCE(MAX(\"ORDRE\"), 0) + " + (i + 1) + " from " + tCalendarItemGroup.getQuotedName() + " )");
194
                values.add(row);
195
            }
112 ilm 196
 
141 ilm 197
            try {
198
                ids.addAll(SQLRowValues.insertIDs(tCalendarItemGroup, "(" + SQLSyntax.quoteIdentifiers(fields) + ") " + syntax.getValues(values, fields.size())));
199
            } catch (Exception e) {
200
                e.printStackTrace();
112 ilm 201
            }
141 ilm 202
        } else {
203
            SQLRowValues v = new SQLRowValues(tCalendarItemGroup);
204
            v.put("NAME", name);
205
            v.put("DESCRIPTION", description);
206
            int i = 0;
207
            try {
208
                for (i = 0; i < numberOfRowToCreate; i++) {
209
                    ids.add(v.insert().getIDNumber());
112 ilm 210
                }
141 ilm 211
            } catch (SQLException e) {
212
                throw new IllegalStateException("cannot insert rowvalues " + i + " [" + numberOfRowToCreate + "]", e);
112 ilm 213
            }
214
        }
215
 
216
        return ids;
217
    }
218
 
219
    // Multiple Insert
220
    public List<Number> multipleInsertOperation(List<Number> calendarGroupIds, int idSite, String status, String type, String description, int idUser, String plannerUid, String plannerXML) {
221
 
222
        final List<Number> ids = new ArrayList<Number>();
223
        int size = calendarGroupIds.size();
141 ilm 224
        if (this.getTable().getServer().getSQLSystem().equals(SQLSystem.POSTGRESQL)) {
225
            final SQLSyntax syntax = this.getTable().getDBSystemRoot().getSyntax();
226
            final List<String> fields = Arrays.asList("ID_SITE", "STATUS", "TYPE", "DESCRIPTION", "PLANNER_UID", "PLANNER_XML", "ID_USER_COMMON", "ID_CALENDAR_ITEM_GROUP", "ORDRE");
227
            final List<List<String>> values = new ArrayList<List<String>>(size);
228
            for (int i = 0; i < size; i++) {
229
                final List<String> row = new ArrayList<String>(fields.size());
230
                row.add(String.valueOf(idSite));
231
                row.add(syntax.quoteString(status));
232
                row.add(syntax.quoteString(type));
233
                row.add(syntax.quoteString(description));
234
                row.add(syntax.quoteString(plannerUid));
235
                row.add(syntax.quoteString(plannerXML));
236
                row.add(String.valueOf(idUser));
237
                row.add(String.valueOf(calendarGroupIds.get(i).longValue()));
238
                row.add("( select COALESCE(MAX(\"ORDRE\"), 0) + " + (i + 1) + " from " + this.getTable().getQuotedName() + " )");
239
                values.add(row);
240
            }
112 ilm 241
 
141 ilm 242
            try {
243
                ids.addAll(SQLRowValues.insertIDs(getTable(), "(" + SQLSyntax.quoteIdentifiers(fields) + ") " + syntax.getValues(values, fields.size())));
244
            } catch (Exception e) {
245
                e.printStackTrace();
112 ilm 246
            }
141 ilm 247
        } else {
248
            final SQLRowValues v = new SQLRowValues(getTable());
249
            v.put("ID_SITE", idSite);
250
            v.put("STATUS", status);
251
            v.put("TYPE", type);
252
            v.put("DESCRIPTION", description);
253
            v.put("PLANNER_UID", plannerUid);
254
            v.put("PLANNER_XML", plannerXML);
255
            v.put("ID_USER_COMMON", idUser);
256
            int i = 0;
257
            try {
258
                for (i = 0; i < size; i++) {
259
                    v.put("ID_CALENDAR_ITEM_GROUP", calendarGroupIds.get(i));
260
                    ids.add(v.insert().getIDNumber());
112 ilm 261
                }
141 ilm 262
            } catch (SQLException e) {
263
                throw new IllegalStateException("cannot insert rowvalues " + i + " [" + size + "]", e);
112 ilm 264
            }
265
        }
266
 
267
        return ids;
268
    }
269
 
270
    private void multipleInsertCalendarItems(List<Number> calendarGroupIds, List<Number> operationsIds, List<DateRange> ranges, String summary, String description, String status) {
271
        final int size = calendarGroupIds.size();
272
        final DBRoot root = ComptaPropsConfiguration.getInstanceCompta().getRootSociete();
273
        final SQLTable tCalendarItem = root.getTable("CALENDAR_ITEM");
274
        //
275
        final List<String> queries = new ArrayList<String>(size);
276
        final List<ResultSetHandler> handlers = new ArrayList<ResultSetHandler>(size);
277
        final ResultSetHandler handler = new ResultSetHandler() {
278
 
279
            @Override
280
            public Object handle(ResultSet rs) throws SQLException {
281
                return null;
282
            }
283
        };
284
 
285
        for (int i = 0; i < size; i++) {
286
            final DateRange dateRange = ranges.get(i);
287
            String query = "INSERT INTO " + tCalendarItem.getQuotedName();
288
            query += " (\"START\", \"END\", \"DURATION_S\", \"SUMMARY\", \"DESCRIPTION\", \"FLAGS\", \"STATUS\", \"ID_CALENDAR_ITEM_GROUP\", \"SOURCE_ID\", \"SOURCE_TABLE\", \"ORDRE\")";
289
            query += " select ";
290
            query += tCalendarItem.getField("START").getType().toString(new Date(dateRange.getStart())) + ", ";
291
            query += tCalendarItem.getField("END").getType().toString(new Date(dateRange.getStop())) + ", ";
292
            long duration = (dateRange.getStop() - dateRange.getStart()) / 1000;
293
            query += tCalendarItem.getField("DURATION_S").getType().toString(duration) + ", ";
294
            query += SQLBase.quoteStringStd(summary) + ", ";
295
            query += SQLBase.quoteStringStd(description) + ", ";
296
            query += SQLBase.quoteStringStd("planned") + ", ";
297
            query += SQLBase.quoteStringStd(status) + ", ";
298
            query += calendarGroupIds.get(i) + ", ";
299
            query += operationsIds.get(i) + ", ";
300
            query += SQLBase.quoteStringStd(ModuleOperation.TABLE_OPERATION) + ", ";
301
            query += "COALESCE(MAX(\"ORDRE\"), 0) + 1 ";
302
            query += "FROM " + tCalendarItem.getQuotedName();
303
            queries.add(query);
304
            handlers.add(handler);
305
 
306
        }
307
        try {
308
            SQLUtils.executeMultiple(this.getTable().getDBSystemRoot(), queries, handlers);
309
        } catch (Exception e) {
310
            e.printStackTrace();
311
        }
312
    }
313
 
314
    public void setDateStart(Date dateStart) {
315
        this.dateStart = dateStart;
316
        this.getDateRangeTable().setStartDate(dateStart);
317
    }
318
 
319
    @Override
320
    protected Set<String> createRequiredNames() {
321
        Set<String> s = new HashSet<String>();
322
        s.add("ID_SITE");
323
        s.add("ID_USER_COMMON");
324
        s.add("TYPE");
325
        s.add("STATUS");
326
        return s;
327
    }
328
 
329
    @Override
330
    public synchronized ValidState getValidState() {
331
        DateRangePlannerPanel t = this.getDateRangeTable();
332
        ValidState e = super.getValidState();
333
        e = e.and(ValidState.createCached(t.getJDateStart().getValue() != null, "Date de début incorrecte"));
334
        e = e.and(ValidState.createCached(t.getJDateEnd().getValue() != null, "Date de fin incorrecte"));
335
        return e;
336
    }
337
}