OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 174 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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.sales.pos.ui;
15
 
16
import org.openconcerto.erp.core.sales.pos.model.Article;
17
import org.openconcerto.erp.core.sales.pos.model.Categorie;
18
import org.openconcerto.ui.touch.ScrollableList;
182 ilm 19
import org.openconcerto.utils.QuickOrderedMap;
20
import org.openconcerto.utils.StringUtils;
18 ilm 21
 
22
import java.awt.Color;
142 ilm 23
import java.awt.FlowLayout;
18 ilm 24
import java.awt.Font;
25
import java.awt.Graphics;
26
import java.awt.Graphics2D;
27
import java.awt.GridBagConstraints;
28
import java.awt.GridBagLayout;
29
import java.awt.RenderingHints;
142 ilm 30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
18 ilm 32
import java.awt.event.MouseAdapter;
33
import java.awt.event.MouseEvent;
83 ilm 34
import java.math.BigDecimal;
67 ilm 35
import java.math.RoundingMode;
18 ilm 36
 
37
import javax.swing.JPanel;
38
import javax.swing.event.ListSelectionEvent;
39
import javax.swing.event.ListSelectionListener;
40
 
174 ilm 41
public class ArticleSelector extends JPanel implements CaisseListener {
18 ilm 42
    private ArticleModel model;
43
    private ScrollableList list;
44
    private StatusBar comp;
45
    private CaisseControler controller;
46
 
47
    ArticleSelector(final CaisseControler controller) {
48
        this.controller = controller;
49
        this.controller.addCaisseListener(this);
50
 
51
        this.setLayout(new GridBagLayout());
52
        GridBagConstraints c = new GridBagConstraints();
53
        c.gridx = 0;
54
        c.gridy = 0;
55
        c.weightx = 1;
56
        c.fill = GridBagConstraints.BOTH;
174 ilm 57
        this.comp = new StatusBar();
58
        this.comp.setLayout(new FlowLayout(FlowLayout.LEFT));
59
        this.comp.setTitle("Articles");
142 ilm 60
        final POSButton bSwitch = new POSButton("-");
61
        bSwitch.setForeground(Color.WHITE);
62
        bSwitch.setBackground(CaissePanel.DARK_BLUE);
174 ilm 63
        this.comp.add(bSwitch);
64
        this.add(this.comp, c);
18 ilm 65
 
66
        c.weighty = 1;
67
        c.gridy++;
174 ilm 68
        this.model = new ArticleModel();
69
        this.model.setCategorie(null);
18 ilm 70
 
174 ilm 71
        final Font f;
72
        if (controller.getPOSConf().getScreenWidth() < 1280) {
73
            f = new Font("Arial", Font.PLAIN, 18);
74
        } else {
75
            f = new Font("Arial", Font.PLAIN, 21);
76
        }
77
 
78
        this.list = new ScrollableList(this.model) {
83 ilm 79
            int maxStringWidth = 0;
80
 
18 ilm 81
            @Override
82
            public void paint(Graphics g) {
83 ilm 83
 
174 ilm 84
                if (this.maxStringWidth == 0) {
83 ilm 85
                    g.setFont(f);
86
                    int w = this.getWidth();
87
                    int priceWidth = (int) g.getFontMetrics(f).getStringBounds(getPrice(BigDecimal.valueOf(999)), g).getWidth();
88
                    int maxW = w - priceWidth - getLeftMargin();
89
                    String str = "a";
90
                    int strW;
91
                    do {
92
                        strW = (int) g.getFontMetrics(f).getStringBounds(str, g).getWidth();
93
                        str += "a";
94
                    } while (strW < maxW);
95
 
174 ilm 96
                    this.maxStringWidth = Math.max(1, str.length() - 1);
83 ilm 97
 
98
                }
18 ilm 99
                super.paint(g);
100
                g.setColor(Color.GRAY);
101
                g.drawLine(0, 0, 0, this.getHeight());
102
            }
103
 
104
            @Override
105
            public void paintCell(Graphics g, Object object, int index, boolean isSelected, int posY) {
106
                Article article = (Article) object;
182 ilm 107
                paintArticle(f, g, article, isSelected, posY, this.getWidth(), this.getCellHeight(), this.maxStringWidth, getLeftMargin(), false);
18 ilm 108
 
109
            }
110
        };
111
 
174 ilm 112
        this.list.setFixedCellHeight(64);
113
        this.list.setOpaque(true);
114
        this.add(this.list, c);
115
        this.list.addListSelectionListener(new ListSelectionListener() {
18 ilm 116
 
117
            @Override
174 ilm 118
            public void valueChanged(ListSelectionEvent e) {
119
                Object sel = ArticleSelector.this.list.getSelectedValue();
120
                if (sel != null && !e.getValueIsAdjusting()) {
121
                    Article article = (Article) sel;
122
                    controller.setArticleSelected(article);
123
                }
124
 
125
            }
126
        });
127
 
128
        this.list.addMouseListener(new MouseAdapter() {
129
            @Override
18 ilm 130
            public void mouseClicked(MouseEvent e) {
174 ilm 131
 
132
                Object sel = ArticleSelector.this.list.getSelectedValue();
133
                if (sel != null) {
134
                    int nb = e.getClickCount();
135
                    if (nb == 1) {
18 ilm 136
                        Article article = (Article) sel;
174 ilm 137
                        controller.addArticle(article);
138
                    } else if (nb > 1) {
139
                        Article article = (Article) sel;
18 ilm 140
                        controller.incrementArticle(article);
141
                        controller.setArticleSelected(article);
142
                    }
143
                }
144
            }
145
        });
142 ilm 146
 
147
        bSwitch.addActionListener(new ActionListener() {
148
 
83 ilm 149
            @Override
142 ilm 150
            public void actionPerformed(ActionEvent e) {
83 ilm 151
                controller.switchListMode();
142 ilm 152
 
83 ilm 153
            }
154
        });
174 ilm 155
        this.comp.addMouseListener(new MouseAdapter() {
149 ilm 156
            @Override
157
            public void mousePressed(MouseEvent e) {
174 ilm 158
                ArticleSelector.this.list.scrollToOffset(0);
149 ilm 159
            }
160
        });
18 ilm 161
    }
162
 
163
    public ArticleModel getModel() {
164
        return this.model;
165
    }
166
 
167
    @Override
168
    public void caisseStateChanged() {
169
 
174 ilm 170
        final Article articleSelected = this.controller.getArticleSelected();
18 ilm 171
        if (articleSelected == null) {
174 ilm 172
            this.list.clearSelection();
18 ilm 173
            return;
174
        }
175
 
176
        Object selectedValue = null;
177
        try {
174 ilm 178
            selectedValue = this.list.getSelectedValue();
18 ilm 179
        } catch (Exception e) {
180
            e.printStackTrace();
181
        }
149 ilm 182
        if (!articleSelected.equals(selectedValue)) {
18 ilm 183
            Categorie c = articleSelected.getCategorie();
174 ilm 184
            this.model.setCategorie(c);
185
            this.list.setSelectedValue(articleSelected, true);
18 ilm 186
        }
187
 
188
    }
189
 
182 ilm 190
    public static void paintArticle(final Font f, Graphics g, Article article, boolean isSelected, int posY, int cellWidth, int cellHeight, int maxWidth, int leftMargin, boolean showCode) {
83 ilm 191
 
192
        g.setFont(f);
193
 
194
        if (isSelected) {
195
            g.setColor(new Color(232, 242, 254));
196
        } else {
197
            g.setColor(Color.WHITE);
198
        }
199
        g.fillRect(0, posY, cellWidth, cellHeight);
200
 
201
        //
202
        g.setColor(Color.GRAY);
203
        g.drawLine(0, posY + cellHeight - 1, cellWidth, posY + cellHeight - 1);
204
 
205
        if (isSelected) {
206
            g.setColor(Color.BLACK);
207
        } else {
208
            g.setColor(Color.GRAY);
209
        }
210
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
211
 
212
        String label = article.getName();
182 ilm 213
        if (showCode && article.getCode() != null && !article.getCode().isEmpty()) {
214
            label += " [" + article.getCode() + "]";
215
        }
216
        StringBuilder declinaisons = null;
217
        QuickOrderedMap<String, String> decls = article.getDeclinaisons();
218
        if (decls != null && !decls.isEmpty()) {
219
            declinaisons = new StringBuilder();
220
            for (int i = 0; i < decls.size(); i++) {
221
                declinaisons.append(StringUtils.firstUpThenLow(decls.getKey(i)));
222
                declinaisons.append(": ");
223
                declinaisons.append(decls.getValue(i));
224
                declinaisons.append("  ");
225
            }
226
        }
83 ilm 227
 
228
        if (label.length() > maxWidth * 2) {
229
            label = label.substring(0, maxWidth * 2) + "...";
230
        }
231
        String label2 = null;
232
        if (label.length() > maxWidth) {
233
            String t = label.substring(0, maxWidth).trim();
234
            int lastSpace = t.lastIndexOf(' ');
235
            if (lastSpace <= 0) {
236
                lastSpace = maxWidth;
237
            }
238
            label2 = label.substring(lastSpace).trim();
239
            label = label.substring(0, lastSpace).trim();
240
            if (label2.length() > maxWidth) {
241
                label2 = label2.substring(0, maxWidth) + "...";
242
            }
243
        }
182 ilm 244
        if (declinaisons != null) {
245
            String textDeclinaisons = declinaisons.toString();
246
            if (label2 == null) {
247
                label2 = textDeclinaisons;
248
            } else {
249
                if (label2.length() + textDeclinaisons.length() > maxWidth) {
250
                    label2 = label2.substring(0, maxWidth - textDeclinaisons.length()) + "...";
251
                }
252
                label2 = label2 + " " + textDeclinaisons;
253
            }
83 ilm 254
 
182 ilm 255
        }
256
 
257
        final BigDecimal priceInCents = article.getPriceWithTax(BigDecimal.ONE);
83 ilm 258
        String euro = getPrice(priceInCents);
259
 
260
        int wEuro = (int) g.getFontMetrics().getStringBounds(euro, g).getWidth();
261
        if (label2 == null) {
262
            g.drawString(label, leftMargin, posY + 39);
263
        } else {
264
            g.drawString(label, leftMargin, posY + 26);
265
            g.drawString(label2, leftMargin, posY + 52);
266
        }
174 ilm 267
 
268
        if (isSelected) {
269
            g.setColor(new Color(232, 242, 254));
270
        } else {
271
            g.setColor(Color.WHITE);
272
        }
273
        g.fillRect(cellWidth - wEuro - 12, posY + 1, wEuro + 12, cellHeight - 2);
274
 
275
        // Price
276
        if (isSelected) {
277
            g.setColor(Color.BLACK);
278
        } else {
279
            g.setColor(Color.GRAY);
280
        }
281
        if (article.getSalesUnit() != null) {
282
            String unit = "/" + article.getSalesUnit();
283
            int wUnit = (int) g.getFontMetrics().getStringBounds(unit, g).getWidth();
284
            g.drawString(euro, cellWidth - 5 - wEuro, posY + 28);
285
            g.drawString(unit, cellWidth - 5 - wUnit, posY + 50);
286
        } else {
287
            g.drawString(euro, cellWidth - 5 - wEuro, posY + 39);
288
        }
289
 
83 ilm 290
    }
291
 
292
    public int getLeftMargin() {
174 ilm 293
        if (this.controller.getPOSConf().getScreenWidth() < 1280) {
294
            return 3;
295
        }
83 ilm 296
        return 10;
297
    }
298
 
299
    public static String getPrice(final BigDecimal price) {
300
        return TicketCellRenderer.centsToString(price.movePointRight(2).setScale(0, RoundingMode.HALF_UP).intValue()) + "€";
301
    }
302
 
18 ilm 303
}