BrightSide Workbench Full Report + Source Code
ValuesGrid.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2012 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.valuation;
20 
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.EnumSet;
24 import org.turro.elephant.util.DecimalFormats;
25 import org.turro.i18n.I_;
26 import org.turro.zkoss.grid.PagingGrid;
27 import org.turro.zkoss.input.ExpressionInput;
28 import org.turro.zkoss.label.AbstractLabel;
29 import org.turro.zkoss.label.LabelTip;
30 import org.turro.zul.frame.Framework;
31 import org.zkoss.zk.ui.Component;
32 import org.zkoss.zk.ui.event.Event;
33 import org.zkoss.zk.ui.event.EventListener;
34 import org.zkoss.zk.ui.event.Events;
35 import org.zkoss.zul.*;
36 import org.zkoss.zul.impl.XulElement;
37 
42 public class ValuesGrid extends PagingGrid {
43 
44  protected ValuationModel model;
45  protected String currencyFormat = "#0.00",
46  unitFormat = "#0.000";
47  protected boolean showUnits = false;
48  protected ArrayList<XulElement> unitHeads = new ArrayList<XulElement>();
49 
50  public ValuationModel getValuationModel() {
51  return model;
52  }
53 
54  public void setModes(Collection<MarginOverCostMode> marginModes, Collection<PropossedPriceMode> priceModes) {
55  model.setMarginModes(marginModes);
56  model.setPriceModes(priceModes);
57  refreshRows();
58  }
59 
60  public void setShowUnits(boolean showUnits) {
61  this.showUnits = showUnits;
62  for(XulElement xe : unitHeads) {
63  xe.setVisible(showUnits);
64  }
65  }
66 
67  protected void addRows() {
68  Rows rows = getRows(true);
69  rows.getChildren().clear();
70 
71  for(Value value : model.getRootValues()) {
72  processValue(value);
73  }
74 
75  refreshRows();
76 
77  setRowCount(rows.getChildren().size());
78  }
79 
80  private void processValue(Value value) {
81  Row row = new Row();
82  row.setValue(value);
83 
84  getRows().appendChild(row);
85 
86  if(value.getChildren() != null) {
87  for(Value child : value.getChildren()) {
88  processValue(child);
89  }
90  }
91 
92  if(value.getResources() != null) {
93  for(Resource res : value.getResources()) {
94  Row rowRes = new Row();
95  rowRes.setValue(res);
96  getRows().appendChild(rowRes);
97  }
98  }
99  }
100 
101  public void refreshRows() {
102  for(Object row : getRows().getChildren()) {
103  if(row instanceof Row) {
104  if(((Row) row).getValue() instanceof ValuationItem) {
105  refreshValue((Row) row, (ValuationItem) ((Row) row).getValue());
106  }
107  }
108  }
109  refreshFoot(getFoot());
110  }
111 
112  protected void refreshValue(Row row, final ValuationItem value) {
113  row.getChildren().clear();
114 
115  final EnumSet<ResourceStatus> status = value.getStatus();
116 
117  row.setVisible(isVisible(value));
118  row.setSclass(value.getType() + "-row");
119 
120  Hlayout hbox = new Hlayout();
121  Space s = new Space();
122  s.setWidth(value.getLevel() * 15 + "px");
123  hbox.appendChild(s);
124 
125  if(value instanceof Value) {
126  Toolbarbutton breakdown = new Toolbarbutton();
127  breakdown.setImage(getBreakdownImage(value));
128  breakdown.addEventListener(Events.ON_CLICK, new EventListener() {
129  @Override
130  public void onEvent(Event event) throws Exception {
131  changeBreakdownState(value);
132  refreshRows();
133  }
134  });
135  hbox.appendChild(breakdown);
136  }
137  hbox.appendChild(new Image("/_zul/images/" + value.getType() + ".png"));
138  hbox.appendChild(new LabelTip(value.getName()));
139  if(value.getUsage() != null) {
140  hbox.appendChild(new Space());
141  hbox.appendChild(new Image("/_zul/images/" + value.getUsage().getType() + ".png"));
142  hbox.appendChild(new LabelTip(value.getUsage().getName()));
143  }
144  row.appendChild(hbox);
145 
146  if(value instanceof Value) {
147  if(((Value) value).getExpressedUnits() == 0.0d) {
148  row.appendChild(new Space());
149  } else {
150  row.appendChild(new Label(DecimalFormats.format(((Value) value).getExpressedUnits(), unitFormat)));
151  }
152  } else {
153  row.appendChild(new Space());
154  }
155 
156  row.appendChild(new Label(DecimalFormats.format(value.getEstimatedUnits(), unitFormat)));
157 
158  row.appendChild(new Label(DecimalFormats.format(value.getRealUnits(), unitFormat)));
159 
160  row.appendChild(new AbstractLabel(DecimalFormats.format(value.getEstimatedCost(), currencyFormat)) {
161  @Override
162  protected void doSomething() {
163  if(status.contains(ResourceStatus.RESOURCE_NO_ESTIMATED_COST)) {
164  setSclass("warnLabel");
165  final Component comp = this;
166  addEventListener(Events.ON_CLICK, new EventListener() {
167  @Override
168  public void onEvent(Event event) throws Exception {
169  showTooltip(comp, value);
170  }
171  });
172  }
173  }
174  });
175 
176  row.appendChild(new AbstractLabel(DecimalFormats.format(value.getRealCost(), currencyFormat)) {
177  @Override
178  protected void doSomething() {
179  if(status.contains(ResourceStatus.RESOURCE_NO_COST)) {
180  setSclass("warnLabel");
181  final Component comp = this;
182  addEventListener(Events.ON_CLICK, new EventListener() {
183  @Override
184  public void onEvent(Event event) throws Exception {
185  showTooltip(comp, value);
186  }
187  });
188  }
189  }
190  });
191 
192  row.appendChild(new Label(DecimalFormats.format(value.getEstimatedPrice(), currencyFormat)));
193 
194  row.appendChild(new Label(DecimalFormats.format(value.getRealPrice(), currencyFormat)));
195 
196  row.appendChild(getFinalPriceCell(value, status));
197 
198  row.appendChild(new AbstractLabel(DecimalFormats.formatPercent(value.getRealMargin())) {
199  @Override
200  protected void doSomething() {
201  if(status.contains(ResourceStatus.RESOURCE_UNDER_MARGIN)) {
202  setSclass("warnLabel");
203  final Component comp = this;
204  addEventListener(Events.ON_CLICK, new EventListener() {
205  @Override
206  public void onEvent(Event event) throws Exception {
207  showTooltip(comp, value);
208  }
209  });
210  }
211  }
212  });
213 
214  row.appendChild(new Label(DecimalFormats.format(value.getMarketPrice(), currencyFormat)));
215  }
216 
217  protected void refreshFoot(Foot foot) {
218  foot.setSclass("valuation-foot-row");
219  ((Footer) foot.getChildren().get(1)).setLabel(DecimalFormats.format(model.getExpressedUnits(), unitFormat));
220  ((Footer) foot.getChildren().get(2)).setLabel(DecimalFormats.format(model.getEstimatedUnits(), unitFormat));
221  ((Footer) foot.getChildren().get(3)).setLabel(DecimalFormats.format(model.getRealUnits(), unitFormat));
222  ((Footer) foot.getChildren().get(4)).setLabel(DecimalFormats.format(model.getEstimatedCost(), currencyFormat));
223  ((Footer) foot.getChildren().get(5)).setLabel(DecimalFormats.format(model.getRealCost(), currencyFormat));
224  ((Footer) foot.getChildren().get(6)).setLabel(DecimalFormats.format(model.getEstimatedPrice(), currencyFormat));
225  ((Footer) foot.getChildren().get(7)).setLabel(DecimalFormats.format(model.getRealPrice(), currencyFormat));
226  ((Footer) foot.getChildren().get(8)).setLabel(DecimalFormats.format(model.getAsModePrice(), currencyFormat));
227  ((Footer) foot.getChildren().get(9)).setLabel(DecimalFormats.formatPercent(model.getRealMargin()));
228  ((Footer) foot.getChildren().get(10)).setLabel(DecimalFormats.format(model.getMarketPrice(), currencyFormat));
229  }
230 
231  protected void addColumns() {
232  Auxhead ah = new Auxhead();
233  appendChild(ah);
234 
235  Auxheader ahr = new Auxheader();
236  ah.appendChild(ahr);
237 
238  ahr = new Auxheader(I_.get("Units"));
239  ahr.setAlign("center");
240  ahr.setColspan(3);
241  ah.appendChild(ahr);
242  unitHeads.add(ahr);
243 
244  ahr = new Auxheader(I_.get("Cost"));
245  ahr.setAlign("center");
246  ahr.setColspan(2);
247  ah.appendChild(ahr);
248 
249  ahr = new Auxheader(I_.get("Price"));
250  ahr.setAlign("center");
251  ahr.setColspan(5);
252  ah.appendChild(ahr);
253 
254  Columns cols = new Columns();
255  cols.setSizable(true);
256  appendChild(cols);
257 
258  Column col = new Column();
259  col.setLabel("");
260  cols.appendChild(col);
261 
262  col = new Column();
263  col.setLabel(I_.get("Expressed"));
264  col.setAlign("right");
265  col.setWidth("100px");
266  cols.appendChild(col);
267  unitHeads.add(col);
268 
269  col = new Column();
270  col.setLabel(I_.get("Estimated"));
271  col.setAlign("right");
272  col.setWidth("100px");
273  cols.appendChild(col);
274  unitHeads.add(col);
275 
276  col = new Column();
277  col.setLabel(I_.get("Real"));
278  col.setAlign("right");
279  col.setWidth("100px");
280  cols.appendChild(col);
281  unitHeads.add(col);
282 
283  col = new Column();
284  col.setLabel(I_.get("Estimated"));
285  col.setAlign("right");
286  col.setWidth("100px");
287  cols.appendChild(col);
288 
289  col = new Column();
290  col.setLabel(I_.get("Real"));
291  col.setAlign("right");
292  col.setWidth("100px");
293  cols.appendChild(col);
294 
295  col = new Column();
296  col.setLabel(I_.get("Estimated"));
297  col.setAlign("right");
298  col.setWidth("100px");
299  cols.appendChild(col);
300 
301  col = new Column();
302  col.setLabel(I_.get("Real"));
303  col.setAlign("right");
304  col.setWidth("100px");
305  cols.appendChild(col);
306 
307  col = new Column();
308  col.setLabel(I_.get("Final"));
309  //col.setAlign("right");
310  col.setWidth("140px");
311  cols.appendChild(col);
312 
313  col = new Column();
314  col.setLabel(I_.get("Profit margin"));
315  col.setAlign("right");
316  col.setWidth("100px");
317  cols.appendChild(col);
318 
319  col = new Column();
320  col.setLabel(I_.get("Market"));
321  col.setAlign("right");
322  col.setWidth("100px");
323  cols.appendChild(col);
324 
325  Foot foot = createFoot();
326 
327  Footer footer = new Footer();
328  foot.appendChild(footer);
329 
330  footer = new Footer();
331  footer.setAlign("right");
332  foot.appendChild(footer);
333  unitHeads.add(footer);
334 
335  footer = new Footer();
336  footer.setAlign("right");
337  foot.appendChild(footer);
338  unitHeads.add(footer);
339 
340  footer = new Footer();
341  footer.setAlign("right");
342  foot.appendChild(footer);
343  unitHeads.add(footer);
344 
345  footer = new Footer();
346  footer.setAlign("right");
347  foot.appendChild(footer);
348 
349  footer = new Footer();
350  footer.setAlign("right");
351  foot.appendChild(footer);
352 
353  footer = new Footer();
354  footer.setAlign("right");
355  foot.appendChild(footer);
356 
357  footer = new Footer();
358  footer.setAlign("right");
359  foot.appendChild(footer);
360 
361  footer = new Footer();
362  footer.setAlign("right");
363  foot.appendChild(footer);
364 
365  footer = new Footer();
366  footer.setAlign("right");
367  foot.appendChild(footer);
368 
369  footer = new Footer();
370  footer.setAlign("right");
371  foot.appendChild(footer);
372 
374  }
375 
376  protected String getBreakdownImage(ValuationItem value) {
377  if(isShowBreakdown(value)) {
378  return "/_zul/images/breakdown-open.png";
379  } else {
380  return "/_zul/images/breakdown-closed.png";
381  }
382  }
383 
384  protected void changeBreakdownState(ValuationItem value) {
385  if(value.getData() instanceof NodeData) {
386  ((NodeData) value.getData()).changeState();
387  }
388  }
389 
390  protected boolean isShowBreakdown(ValuationItem value) {
391  if(value.getData() instanceof NodeData) {
392  return ((NodeData) value.getData()).showBreakdown;
393  }
394  return true;
395  }
396 
397  protected boolean isVisible(ValuationItem value) {
398  Value tmp = value.getParent();
399  while(tmp != null) {
400  if(tmp.getData() instanceof NodeData) {
401  if(!((NodeData) tmp.getData()).showBreakdown) {
402  return false;
403  }
404  }
405  tmp = tmp.getParent();
406  }
407  return true;
408  }
409 
410  private void showTooltip(Component comp, ValuationItem value) {
411  Popup popup = Framework.getCurrent().getGlobalPopup();
412  Include include = new Include("/WEB-INF/_zul/erp/workorder/valuationStatus.zul");
413  include.setDynamicProperty("value", value);
414  popup.appendChild(include);
415  popup.open(comp, "after_end");
416  }
417 
418  private Hlayout getFinalPriceCell(final ValuationItem value, EnumSet<ResourceStatus> status) {
419  Hlayout hbox = new Hlayout();
420  final ExpressionInput finalPrice = new ExpressionInput();
421  finalPrice.setFormat(currencyFormat);
422  finalPrice.setValue(value.getAsModePrice());
423  finalPrice.setInplace(true);
424  finalPrice.setHflex("true");
425  finalPrice.addEventListener(Events.ON_CHANGE, new EventListener() {
426  @Override
427  public void onEvent(Event event) throws Exception {
428  value.setFinalPrice(((Number) finalPrice.getNumber()).doubleValue());
429  Events.postEvent(new Event(Events.ON_CHANGE, ValuesGrid.this));
430  refreshRows();
431  }
432  });
433  hbox.appendChild(finalPrice);
434  Vlayout vbox = new Vlayout();
435  vbox.setWidth("14px");
436  vbox.setSpacing("0px");
437  hbox.appendChild(vbox);
438  String type = ResourceStatus.getType(status);
439  if(type != null) {
440  final Image img = new Image("/_zul/images/12/" + type + ".png");
441  img.setStyle("cursor:pointer");
442  img.addEventListener(Events.ON_CLICK, new EventListener() {
443  @Override
444  public void onEvent(Event event) throws Exception {
445  showTooltip(img, value);
446  }
447  });
448  vbox.appendChild(img);
449  }
450  if(status.contains(ResourceStatus.RESOURCE_UNDER_COST)) {
451  final Image img = new Image("/_zul/images/12/warn.png");
452  img.setStyle("cursor:pointer");
453  img.addEventListener(Events.ON_CLICK, new EventListener() {
454  @Override
455  public void onEvent(Event event) throws Exception {
456  showTooltip(img, value);
457  }
458  });
459  vbox.appendChild(img);
460  }
461  return hbox;
462  }
463 
464 }
static String formatPercent(double value)
static String format(Number value, String pattern)
static String get(String msg)
Definition: I_.java:41
ValuationModel getValuationModel()
Definition: ValuesGrid.java:50
ArrayList< XulElement > unitHeads
Definition: ValuesGrid.java:48
boolean isShowBreakdown(ValuationItem value)
void refreshValue(Row row, final ValuationItem value)
void setShowUnits(boolean showUnits)
Definition: ValuesGrid.java:60
boolean isVisible(ValuationItem value)
void changeBreakdownState(ValuationItem value)
void setModes(Collection< MarginOverCostMode > marginModes, Collection< PropossedPriceMode > priceModes)
Definition: ValuesGrid.java:54
String getBreakdownImage(ValuationItem value)
Foot getFoot(boolean create)
Rows getRows(boolean create)
static Framework getCurrent()
Definition: Framework.java:203