BrightSide Workbench Full Report + Source Code
MultiRegisterGrid.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2011 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 package org.turro.financials.register;
19 
20 import java.util.*;
21 import java.util.logging.Level;
22 import java.util.logging.Logger;
23 import org.turro.elephant.context.Application;
24 import org.turro.elephant.context.ElephantContext;
25 import org.turro.elephant.util.DateFormats;
26 import org.turro.elephant.util.Messages;
27 import org.turro.financials.account.AccountCombobox;
28 import org.turro.financials.entity.Account;
29 import org.turro.financials.entity.Register;
30 import org.turro.financials.entity.RegisterEntry;
31 import org.turro.financials.entity.RegisterView;
32 import org.turro.financials.model.AccountCreator;
33 import org.turro.financials.model.AccountSet;
34 import org.turro.financials.model.business.CompanyWrapper;
35 import org.turro.financials.model.register.AccountStringWrapper;
36 import org.turro.financials.model.register.MultiRegisterEntry;
37 import org.turro.financials.model.register.RegisterWrapper;
38 import org.turro.financials.model.register.ViewWrapper;
39 import org.turro.financials.view.ViewListbox;
40 import org.turro.i18n.I_;
41 import org.turro.math.Zero;
42 import org.turro.util.PhraseBuilder;
43 import org.turro.zkoss.grid.CollectionGrid;
44 import org.turro.zkoss.grid.EditableCell;
45 import org.turro.zkoss.grid.EditableColumn;
46 import org.turro.zul.frame.Framework;
47 import org.zkoss.zk.ui.HtmlBasedComponent;
48 import org.zkoss.zul.Row;
49 
54 public class MultiRegisterGrid extends CollectionGrid<MultiRegisterEntry> {
55 
56  private RegisterView lastView = ViewWrapper.getFormalView();
57  private Date lastDate = new Date();
58  private Register register;
59  private boolean autocheck = true, regularizeVAT = false, regularizeIRPF = false;
60 
61  public MultiRegisterGrid() {
62  super(new TreeSet<MultiRegisterEntry>());
63  }
64 
65  public void setRegister(Register register) {
66  this.register = register;
67  if(this.register != null) {
68  for(RegisterEntry entry : this.register.getRegisterEntries()) {
69  getCollection().add(new MultiRegisterEntry(entry));
70  }
71  regularizeVAT = register.isRegularizeVAT();
72  regularizeIRPF = register.isRegularizeIRPF();
73  }
74  }
75 
76  public boolean isAutocheck() {
77  return autocheck;
78  }
79 
80  public void setAutocheck(boolean autocheck) {
81  this.autocheck = autocheck;
82  }
83 
84  public boolean isRegularizeIRPF() {
85  return regularizeIRPF;
86  }
87 
88  public void setRegularizeIRPF(boolean regularizeIRPF) {
89  this.regularizeIRPF = regularizeIRPF;
90  }
91 
92  public boolean isRegularizeVAT() {
93  return regularizeVAT;
94  }
95 
96  public void setRegularizeVAT(boolean regularizeVAT) {
97  this.regularizeVAT = regularizeVAT;
98  }
99 
100  public void doCheck() {
101  checkValues();
102  }
103 
104  public void save(final boolean close) {
105  if(register != null) {
106  register.setRegularizeVAT(regularizeVAT);
107  register.setRegularizeIRPF(regularizeIRPF);
108  final RegisterWrapper wReg = new RegisterWrapper(register, false);
109  if(wReg.checkSave()) {
110  wReg.save();
111  if(close) Framework.getCurrent().closeSelected();
112  } else {
113  PhraseBuilder pb = new PhraseBuilder(I_.get("Closing date"));
114  pb.addWord("\n");
116  if(Application.getApplication().isInRole("finan-model:edit")) {
117  pb.addWord(I_.get("Proceed anyway"));
118  Messages.question().add(pb.toString()).show(() -> {
119  wReg.save();
120  if(close) Framework.getCurrent().closeSelected();
121  });
122  } else {
123  Messages.info(I_.get("Closing date")).add(pb.toString()).show();
124  }
125  }
126  } else {
127  Register reg = null;
128  MultiRegisterEntry lastEntry = null;
129  final HashSet<Register> regs = new HashSet<>();
130  int count = 0;
131  for(Object obj : getRows().getChildren()) {
132  if(obj instanceof Row) {
133  MultiRegisterEntry rentry = (MultiRegisterEntry) ((Row) obj).getValue();
134  if(rentry.isValid()) {
135  if(lastEntry != null && lastEntry.isValid()) {
136  if(!rentry.isSameRegister(lastEntry)) {
137  reg = null;
138  }
139  }
140  if(reg == null) {
141  count = 0;
142  reg = new Register();
143  reg.setRegisterDate(rentry.getDate());
144  reg.setView(rentry.getView());
145  regs.add(reg);
146  }
147  rentry.getEntry().setRegister(reg);
148  rentry.getEntry().setEntryOrder(count++);
149  reg.getRegisterEntries().add(rentry.getEntry());
150  lastEntry = rentry;
151  }
152  }
153  }
154  boolean isSafe = true;
155  for(Register r : regs) {
156  if(!(new RegisterWrapper(r).checkSave())) {
157  isSafe = false;
158  break;
159  }
160  }
161  if(!isSafe) {
162  PhraseBuilder pb = new PhraseBuilder(I_.get("Closing date"));
163  pb.addWord("\n");
165  if(Application.getApplication().isInRole("finan-model:edit")) {
166  pb.addWord(I_.get("Proceed anyway"));
167  Messages.question().add(pb.toString()).show(() -> {
168  for(Register r : regs) {
169  r.setRegularizeVAT(regularizeVAT);
170  r.setRegularizeIRPF(regularizeIRPF);
171  new RegisterWrapper(r).save();
172  }
173  if(close) Framework.getCurrent().closeSelected();
174  });
175  } else {
176  Messages.info(I_.get("Closing date")).add(pb.toString()).show();
177  }
178  } else {
179  for(Register r : regs) {
180  r.setRegularizeVAT(regularizeVAT);
181  r.setRegularizeIRPF(regularizeIRPF);
182  new RegisterWrapper(r).save();
183  }
184  if(close) Framework.getCurrent().closeSelected();
185  }
186  }
187  }
188 
189  public void delete(final boolean close) {
190  final RegisterWrapper wReg = new RegisterWrapper(register, false);
191  Messages.confirmDeletion().show(() -> {
192  if(wReg.checkSave()) {
193  if(wReg.delete() && close) Framework.getCurrent().closeSelected();
194  }
195  });
196  }
197 
198  public void loadPosibleAccounts() {
199  cancelEdition();
201  for(Account acc : accs) {
202  RegisterEntry re = new RegisterEntry();
203  re.setAccount(acc);
204  if(register != null) {
205  re.setRegister(register);
206  register.getRegisterEntries().add(re);
207  }
208  Row row = addNewRow();
209  MultiRegisterEntry mentry = new MultiRegisterEntry(re);
210  initiateRow(row, mentry);
211  }
212  updateRows();
213  }
214 
215  public void loadUsedAccounts() {
216  cancelEdition();
218  for(Account acc : accs) {
219  RegisterEntry re = new RegisterEntry();
220  re.setAccount(acc);
221  if(register != null) {
222  re.setRegister(register);
223  register.getRegisterEntries().add(re);
224  }
225  Row row = addNewRow();
226  MultiRegisterEntry mentry = new MultiRegisterEntry(re);
227  initiateRow(row, mentry);
228  }
229  updateRows();
230  }
231 
232  @Override
233  protected void initiateRow(Row row, MultiRegisterEntry value) {
234  if(value == null) {
235  value = new MultiRegisterEntry(register);
236  row.setSclass("invalid");
237  }
238  if(register == null) {
239  value.setView(lastView);
240  value.setDate(lastDate);
241  }
242  row.setValue(value);
243  }
244 
245  @Override
246  protected boolean deleteRow(Row row) {
247  MultiRegisterEntry mre = (MultiRegisterEntry) row.getValue();
248  if(mre != null) {
249  mre.deleteEntry();
250  }
251  return true;
252  }
253 
254  @Override
255  protected boolean isValid(MultiRegisterEntry v) {
256  return v.isValid();
257  }
258 
259  @Override
260  protected void cellChanged(EditableCell editableCell, Object value) {
261  super.cellChanged(editableCell, value);
262  MultiRegisterEntry mre = (MultiRegisterEntry) editableCell.getRow().getValue();
263  if(value instanceof Double) {
264  if(mre != null) {
265  mre.checkValues(editableCell.getCellIndex());
266  }
267  updateRow(editableCell.getRow());
268  }
269  if(value instanceof RegisterView) {
270  lastView = (RegisterView) value;
271  if(register != null) {
272  register.setView(lastView);
273  setAllValuesAsRegister();
274  }
275  } else if(value instanceof Date) {
276  lastDate = (Date) value;
277  if(register != null) {
278  register.setRegisterDate(lastDate);
279  setAllValuesAsRegister();
280  }
281  }
282  }
283 
284  @Override
285  protected void rowChanged(Row row) {
286  if(autocheck) {
287  checkValues();
288  }
289  super.rowChanged(row);
290  }
291 
292  @Override
293  protected String formatCell(EditableCell editableCell, Object value) {
294  if(value instanceof RegisterView) {
295  RegisterView rv = ((RegisterView) value);
296  return rv.getName();
297  } else if(value instanceof Account) {
298  Account a = ((Account) value);
299  return a.getFullDescription();
300  }
301  return super.formatCell(editableCell, value);
302  }
303 
304  @Override
305  protected HtmlBasedComponent createEditor(EditableCell editableCell) {
306  if(editableCell.getColumn() instanceof EditableColumn) {
307  EditableColumn ec = (EditableColumn) editableCell.getColumn();
308  if(ec.getJavaClass().equals(RegisterView.class)) {
309  Object value = getCellValue(editableCell);
310  ViewListbox vl = new ViewListbox();
311  vl.setMold("select");
312  if(value != null) vl.setObjectValue((RegisterView) value);
313  return vl;
314  } else if(ec.getJavaClass().equals(Account.class)) {
315  Object value = getCellValue(editableCell);
316  AccountCombobox acb = new AccountCombobox();
317  acb.setAllowNotInModelValues(true);
318  acb.setAllowNewAccount(true);
319  if(value != null) acb.setObjectValue((Account) value);
320  return acb;
321  }
322  }
323  return super.createEditor(editableCell);
324  }
325 
326  @Override
327  public void afterCompose() {
328  try {
329  addColumns();
330  } catch (ClassNotFoundException ex) {
331  Logger.getLogger(MultiRegisterGrid.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
332  }
333  super.afterCompose();
334  }
335 
336  private void addColumns() throws ClassNotFoundException {
337  int fractionDigits = CompanyWrapper.getCompanyCurrency().getDefaultFractionDigits();
338  addColumn(I_.get("View"), RegisterView.class,
339  "view", null, 0, false, false).setWidth("110px");
340  addColumn(I_.get("Date"), Date.class,
341  "date", null, fractionDigits, true, false).setWidth("100px");
342  addColumn(I_.get("New"), "boolean",
343  "newRegister", null, 0, false, register != null).setWidth("35px");
344  addColumn(I_.get("Account"), Account.class,
345  "account", null, 0, false, false).setWidth("350px");
346  addColumn(I_.get("Concept"), String.class,
347  "concept", null, 0, false, false);
348  addColumn(I_.get("Debit"), "double",
349  "debit", null, fractionDigits, false, false).setWidth("100px");
350  addColumn(I_.get("Credit"), "double",
351  "credit", null, fractionDigits, false, false).setWidth("100px");
352  addColumn(I_.get("Balance"), "double",
353  "balance", null, fractionDigits, false, true).setWidth("100px");
354  addColumn(I_.get("Account"), "double",
355  "accountBalance", null, fractionDigits, false, true).setWidth("100px");
356  }
357 
358  private void checkValues() {
359  MultiRegisterEntry lastEntry = null;
360  Row lastRow = null;
361  double balance = 0;
362  Map<String, Double> accBal = new HashMap<>();
363  for(Object obj : getRows().getChildren()) {
364  if(obj instanceof Row) {
365  Row row = (Row) obj;
366  MultiRegisterEntry rentry = (MultiRegisterEntry) ((Row) obj).getValue();
367  row.setSclass("");
368  if(rentry.isValid()) {
369  if(lastEntry != null && lastEntry.isValid()) {
370  if(!rentry.isSameRegister(lastEntry)) {
371  balance = 0;
372  accBal = new HashMap<>();
373  if(lastRow != null) {
374  if(Zero.near(lastEntry.getBalance(), 2)) {
375  lastRow.setSclass("endRegister");
376  } else {
377  lastRow.setSclass("endBadRegister");
378  }
379  }
380  }
381  }
382  lastEntry = rentry;
383  lastRow = row;
384  Double accB = accBal.get(rentry.getAccount().getId());
385  if(accB == null) {
386  accB = new AccountStringWrapper(rentry.getAccount().getId())
387  .getBalance(rentry.getView(), rentry.getDate());
388  }
389  if(accB == null) {
390  accB = 0.0;
391  }
392  rentry.setAccountBalance(accB + rentry.getDebit() - rentry.getCredit());
393  accBal.put(rentry.getAccount().getId(), rentry.getAccountBalance());
394  balance += rentry.getDebit() - rentry.getCredit();
395  rentry.setBalance(balance);
396  } else {
397  row.setSclass("invalid");
398  }
399  }
400  }
401  if(lastEntry != null && lastEntry.isValid()) {
402  if(lastRow != null) {
403  if(Zero.near(lastEntry.getBalance(), 2)) {
404  lastRow.setSclass("endRegister");
405  } else {
406  lastRow.setSclass("endBadRegister");
407  }
408  }
409  }
410  updateRows();
411  }
412 
413  private void setAllValuesAsRegister() {
414  if(register != null) {
415  for(Object obj : getRows().getChildren()) {
416  if(obj instanceof Row) {
417  MultiRegisterEntry rentry = (MultiRegisterEntry) ((Row) obj).getValue();
418  rentry.setView(register.getView());
419  rentry.setDate(register.getRegisterDate());
420  }
421  }
422  }
423  updateRows();
424  }
425 
426 }
static final String format(Date d, boolean dateOnly)
static Messages confirmDeletion()
Definition: Messages.java:87
Messages add(String word)
Definition: Messages.java:50
void setAllowNewAccount(boolean allowNewAccount)
void setView(RegisterView view)
Definition: Register.java:163
Set< RegisterEntry > getRegisterEntries()
Definition: Register.java:135
void setRegisterDate(Date registerDate)
Definition: Register.java:127
void initiateRow(Row row, MultiRegisterEntry value)
void cellChanged(EditableCell editableCell, Object value)
HtmlBasedComponent createEditor(EditableCell editableCell)
String formatCell(EditableCell editableCell, Object value)
static String get(String msg)
Definition: I_.java:41
EditableColumn addColumn(String label, Class javaClass, String property, String format, int scale, boolean onlyDate, boolean readOnly)
Object getCellValue(EditableCell editableCell)
Rows getRows(boolean create)
void setAllowNotInModelValues(boolean allowNotInModelValues)
static Framework getCurrent()
Definition: Framework.java:203