OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

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

Rev Author Line No. Line
112 ilm 1
package org.openconcerto.modules.operation;
2
 
150 ilm 3
import java.awt.Component;
4
import java.beans.PropertyChangeEvent;
5
import java.beans.PropertyChangeListener;
112 ilm 6
import java.util.ArrayList;
7
import java.util.Collections;
150 ilm 8
import java.util.LinkedHashMap;
112 ilm 9
import java.util.List;
150 ilm 10
import java.util.Map;
11
import java.util.Map.Entry;
112 ilm 12
 
150 ilm 13
import javax.swing.SwingUtilities;
14
 
15
import org.jopencalendar.model.Flag;
16
import org.jopencalendar.model.JCalendarItem;
17
import org.jopencalendar.ui.MultipleDayView;
18
import org.jopencalendar.ui.WeekView;
19
import org.openconcerto.erp.core.humanresources.payroll.element.SalarieSQLElement;
20
import org.openconcerto.sql.element.SQLElementDirectory;
21
import org.openconcerto.sql.model.SQLRowValues;
22
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
23
import org.openconcerto.sql.model.SQLTable;
24
import org.openconcerto.sql.model.SQLTable.VirtualFields;
25
import org.openconcerto.sql.model.SQLTableEvent;
26
import org.openconcerto.sql.model.SQLTableModifiedListener;
112 ilm 27
import org.openconcerto.sql.users.User;
28
import org.openconcerto.sql.users.UserManager;
150 ilm 29
import org.openconcerto.ui.DisplayabilityListener;
112 ilm 30
import org.openconcerto.ui.list.CheckListItem;
31
 
150 ilm 32
import net.jcip.annotations.GuardedBy;
112 ilm 33
 
150 ilm 34
public class UserOperationListModel extends CheckListModel<User> {
35
 
36
    protected static String formatDuration(int durationMinute) {
37
        int h = durationMinute / 60;
38
        int m = durationMinute % 60;
39
        if (m != 0) {
40
            String mS = String.valueOf(m);
41
            if (m < 10) {
42
                mS = "0" + mS;
43
            }
44
            return h + ":" + mS;
45
        }
46
        return String.valueOf(h);
112 ilm 47
    }
48
 
150 ilm 49
    private static final class UsersListener implements PropertyChangeListener, SQLTableModifiedListener {
50
 
51
        private final UserOperationListModel model;
52
 
53
        protected UsersListener(UserOperationListModel model) {
54
            super();
55
            this.model = model;
56
        }
57
 
58
        @Override
59
        public void tableModified(SQLTableEvent evt) {
60
            this.model.refreshUsers();
61
        }
62
 
63
        @Override
64
        public void propertyChange(PropertyChangeEvent evt) {
65
            this.model.refreshUsers();
66
        }
67
    }
68
 
69
    private final MultipleDayView view;
70
    private final UserManager userMngr;
71
    private final SalarieSQLElement salarieElem;
72
 
73
    // all users to display and their the weekly work time, if null, not a Salarie
74
    @GuardedBy("this")
75
    private Map<User, Integer> usersAndWeeklyMinutes;
76
    private final UsersListener usersL = new UsersListener(this);
77
    // durations by user ID
78
    @GuardedBy("this")
79
    private Map<Integer, Long> allDurations;
80
    @GuardedBy("this")
81
    private Map<Integer, Long> lockedDurations;
82
    private final PropertyChangeListener viewL = new PropertyChangeListener() {
83
        @SuppressWarnings("unchecked")
84
        @Override
85
        public void propertyChange(PropertyChangeEvent evt) {
86
            assert SwingUtilities.isEventDispatchThread();
87
            setDurations((List<List<JCalendarItem>>) evt.getNewValue());
88
            loadContent();
89
        }
90
    };
91
 
92
    public UserOperationListModel(final UserManager userMngr, final SQLElementDirectory dir, final MultipleDayView multipleDayView) {
93
        super(User.class);
94
        this.view = multipleDayView;
95
        this.userMngr = userMngr;
96
        this.salarieElem = dir.getElement(SalarieSQLElement.class);
97
        this.view.addHierarchyListener(new DisplayabilityListener() {
98
            @Override
99
            protected void displayabilityChanged(Component c) {
100
                setRunning(c.isDisplayable());
101
            }
102
        });
103
        // initial value
104
        setRunning(this.view.isDisplayable());
105
    }
106
 
107
    public final void setRunning(final boolean b) {
108
        if (b) {
109
            this.userMngr.addUsersListener(this.usersL);
110
            for (final SQLTable salT : this.salarieElem.createGraph(VirtualFields.PRIMARY_KEY).getGraphTables()) {
111
                salT.addTableModifiedListener(this.usersL);
112
            }
113
            this.view.addPropertyChangeListener(WeekView.CALENDARD_ITEMS_PROPERTY, this.viewL);
114
            // initial value
115
            refreshUsers();
116
        } else {
117
            this.userMngr.removeUsersListener(this.usersL);
118
            for (final SQLTable salT : this.salarieElem.createGraph(VirtualFields.PRIMARY_KEY).getGraphTables()) {
119
                salT.removeTableModifiedListener(this.usersL);
120
            }
121
            this.view.removePropertyChangeListener(WeekView.CALENDARD_ITEMS_PROPERTY, this.viewL);
122
        }
123
    }
124
 
125
    private void refreshUsers() {
126
        synchronized (this) {
127
            this.usersAndWeeklyMinutes = null;
128
        }
129
        SwingUtilities.invokeLater(new Runnable() {
130
            @Override
131
            public void run() {
132
                loadContent();
133
            }
134
        });
135
    }
136
 
137
    private Map<User, Integer> setUsers() {
138
        synchronized (this) {
139
            if (this.usersAndWeeklyMinutes != null) {
140
                return this.usersAndWeeklyMinutes;
141
            }
142
        }
181 ilm 143
        final Map<User, Integer> uInfo = new LinkedHashMap<>();
150 ilm 144
        final SQLRowValues v = new SQLRowValues(this.salarieElem.getTable());
145
        v.putNulls("NOM", "PRENOM");
146
        v.putRowValues("ID_INFOS_SALARIE_PAYE").putNulls("DUREE_HEBDO");
147
        final List<SQLRowValues> rows = SQLRowValuesListFetcher.create(v).fetch();
148
        final List<User> users = new ArrayList<>(this.userMngr.getAllActiveUsers());
112 ilm 149
        // Sort by full name
150
        Collections.sort(users, new UserComparator());
151
        final int size = users.size();
152
        for (int i = 0; i < size; i++) {
150 ilm 153
            final User u = users.get(i);
154
            final String name = u.getName().trim();
181 ilm 155
            final String firstName = u.getFirstName().trim();
150 ilm 156
            Integer minutes = null;
157
            for (SQLRowValues row : rows) {
181 ilm 158
                // Matching Utilisateur <-> Salarié
159
                // Nom et prénom identique
160
                final String sName = row.getString("NOM").trim();
161
                final String sFirstName = row.getString("PRENOM").trim();
162
                if (sName.equalsIgnoreCase(name) && sFirstName.equalsIgnoreCase(firstName)) {
150 ilm 163
                    minutes = (int) row.getForeign("ID_INFOS_SALARIE_PAYE").getFloat("DUREE_HEBDO") * 60;
164
                    break;
112 ilm 165
                }
150 ilm 166
            }
167
            uInfo.put(u, minutes);
112 ilm 168
        }
150 ilm 169
        synchronized (this) {
170
            this.usersAndWeeklyMinutes = Collections.unmodifiableMap(uInfo);
171
        }
172
        return uInfo;
112 ilm 173
    }
150 ilm 174
 
175
    private void setDurations(final List<List<JCalendarItem>> viewItems) {
181 ilm 176
        final Map<Integer, Long> all = OperationCalendarPanel.getDurations(viewItems, null, ModuleOperation.FREE_TIME_FLAG);
177
        final Map<Integer, Long> locked = OperationCalendarPanel.getDurations(viewItems, Flag.getFlag("locked"), ModuleOperation.FREE_TIME_FLAG);
150 ilm 178
        synchronized (this) {
179
            this.allDurations = Collections.unmodifiableMap(all);
180
            this.lockedDurations = Collections.unmodifiableMap(locked);
181
        }
182
    }
183
 
184
    // static to make sure that the returned object doesn't depend on any instance attribute
185
    static protected CheckListItem createItem(final User u, final String label) {
186
        final CheckListItem item = new CheckListItem(u, true) {
187
 
188
            @Override
189
            public Object getKey() {
190
                return u.getId();
191
            }
192
 
193
            @Override
194
            public String toString() {
195
                return label;
196
            }
197
        };
198
        item.setColor(UserColor.getInstance().getColor(u.getId()));
199
        return item;
200
    }
201
 
202
    static private final int getDuration(final Map<Integer, Long> m, final Integer key) {
203
        final Long res = m == null ? null : m.get(key);
204
        return res == null ? 0 : res.intValue();
205
    }
206
 
207
    @Override
208
    public List<CheckListItem> loadItems() {
209
        final Map<User, Integer> usersAndWeeklyMinutes = setUsers();
210
        final Map<Integer, Long> all, locked;
211
        synchronized (this) {
212
            all = this.allDurations;
213
            locked = this.lockedDurations;
214
        }
215
        final List<CheckListItem> res = new ArrayList<>(usersAndWeeklyMinutes.size());
216
        for (final Entry<User, Integer> e : usersAndWeeklyMinutes.entrySet()) {
217
            final User u = e.getKey();
218
            final Integer weeklyMinutes = e.getValue();
219
            final String suffix;
220
            if (weeklyMinutes == null) {
221
                // not a SALARIE
222
                suffix = "";
223
            } else {
181 ilm 224
                // Durée verrouillée
225
                final int d2 = getDuration(locked, u.getId());
150 ilm 226
                // Durée planifiée
227
                final int d = getDuration(all, u.getId());
228
                suffix = " [" + formatDuration(d2) + " / " + formatDuration(d) + " / " + formatDuration(weeklyMinutes) + "]";
229
            }
230
            res.add(createItem(u, (u.getFullName() + suffix).trim()));
231
        }
232
        return res;
233
    }
112 ilm 234
}