1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.ole.sys.document.web;
17
18 import java.io.IOException;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.servlet.jsp.JspException;
23 import javax.servlet.jsp.PageContext;
24 import javax.servlet.jsp.tagext.JspFragment;
25 import javax.servlet.jsp.tagext.Tag;
26
27 import org.kuali.ole.sys.document.AccountingDocument;
28 import org.kuali.ole.sys.document.datadictionary.AccountingLineGroupDefinition;
29 import org.kuali.ole.sys.document.datadictionary.TotalDefinition;
30 import org.kuali.ole.sys.document.web.renderers.CellCountCurious;
31 import org.kuali.ole.sys.document.web.renderers.CollectionPropertiesCurious;
32 import org.kuali.ole.sys.document.web.renderers.GroupErrorsRenderer;
33 import org.kuali.ole.sys.document.web.renderers.GroupTitleLineRenderer;
34 import org.kuali.ole.sys.document.web.renderers.Renderer;
35 import org.kuali.ole.sys.document.web.renderers.RepresentedCellCurious;
36 import org.kuali.rice.kew.api.WorkflowDocument;
37 import org.kuali.rice.krad.util.GlobalVariables;
38
39
40
41
42 public class DefaultAccountingLineGroupImpl implements AccountingLineGroup {
43 protected AccountingLineGroupDefinition groupDefinition;
44 protected JspFragment importLineOverride;
45 protected String collectionPropertyName;
46 protected List<? extends AccountingLineRenderingContext> containers;
47 protected AccountingDocument accountingDocument;
48 protected int cellCount = 0;
49 protected int arbitrarilyHighIndex;
50 protected Map<String, Object> displayedErrors;
51 protected Map<String, Object> displayedWarnings;
52 protected Map<String, Object> displayedInfo;
53 protected boolean canEdit;
54 protected String collectionItemPropertyName;
55 protected List errorKeys;
56
57
58
59
60 public DefaultAccountingLineGroupImpl() {}
61
62
63
64
65
66
67
68
69
70
71
72
73 public void initialize(AccountingLineGroupDefinition groupDefinition, AccountingDocument accountingDocument, List<RenderableAccountingLineContainer> containers, String collectionPropertyName, String collectionItemPropertyName, Map<String, Object> displayedErrors, Map<String, Object> displayedWarnings, Map<String, Object> displayedInfo, boolean canEdit) {
74 this.groupDefinition = groupDefinition;
75 this.accountingDocument = accountingDocument;
76 this.containers = containers;
77 this.collectionPropertyName = collectionPropertyName;
78 this.collectionItemPropertyName = collectionItemPropertyName;
79 this.displayedErrors = displayedErrors;
80 this.displayedWarnings = displayedWarnings;
81 this.displayedInfo = displayedInfo;
82 this.canEdit = canEdit;
83 }
84
85
86
87
88
89
90
91 public void renderEverything(PageContext pageContext, Tag parentTag) throws JspException {
92 if (groupDefinition.isHeaderRendering()) {
93 renderGroupHeader(pageContext, parentTag);
94 }
95 renderAccountingLineContainers(pageContext, parentTag);
96
97 boolean renderTotals = !accountingDocument.getSourceAccountingLines().isEmpty() || !accountingDocument.getTargetAccountingLines().isEmpty();
98 renderTotals &= groupDefinition.getTotals() != null && groupDefinition.getTotals().size() > 0;
99 if (renderTotals) {
100 renderTotals(pageContext, parentTag);
101 }
102 }
103
104
105
106
107
108
109
110 public int getWidthInCells() {
111 if (groupDefinition.getForceColumnCount() > 0)
112 return groupDefinition.getForceColumnCount();
113 if (cellCount > 0)
114 return cellCount;
115
116 int max = 0;
117 for (AccountingLineRenderingContext line : containers) {
118 if (line.getRenderableCellCount() > max) {
119 max = line.getRenderableCellCount();
120 }
121 }
122 cellCount = max;
123 return cellCount;
124 }
125
126
127
128
129
130
131
132
133
134 protected void renderGroupHeader(PageContext pageContext, Tag parentTag) throws JspException {
135 if (importLineOverride != null) {
136 try {
137 importLineOverride.invoke(pageContext.getOut());
138 }
139 catch (IOException ioe) {
140 throw new JspException("Could not render import line override fragment", ioe);
141 }
142 }
143 else {
144 GroupTitleLineRenderer groupTitleLineRenderer = new GroupTitleLineRenderer();
145 groupTitleLineRenderer.setAccountingLineGroupDefinition(groupDefinition);
146 groupTitleLineRenderer.setCellCount(getWidthInCells());
147 groupTitleLineRenderer.setLineCollectionProperty(collectionPropertyName);
148 groupTitleLineRenderer.setAccountingDocument(accountingDocument);
149 groupTitleLineRenderer.setCanEdit(canEdit);
150
151 boolean isGroupEditable = groupDefinition.getAccountingLineAuthorizer().isGroupEditable(accountingDocument, containers, GlobalVariables.getUserSession().getPerson());
152 groupTitleLineRenderer.overrideCanUpload(groupDefinition.isImportingAllowed() && isGroupEditable);
153 groupTitleLineRenderer.setGroupActionsRendered(!this.isDocumentEnrouted() && isGroupEditable);
154
155 groupTitleLineRenderer.render(pageContext, parentTag);
156 groupTitleLineRenderer.clear();
157 }
158
159 renderErrors(pageContext, parentTag);
160 }
161
162
163
164
165
166
167 protected void renderErrors(PageContext pageContext, Tag parentTag) throws JspException {
168 GroupErrorsRenderer errorRenderer = getErrorRenderer();
169 errorRenderer.setErrorKeyMatch(groupDefinition.getErrorKey());
170 errorRenderer.setColSpan(getWidthInCells());
171 errorRenderer.render(pageContext, parentTag);
172
173 moveListToMap(errorRenderer.getErrorsRendered(), getDisplayedErrors());
174 moveListToMap(errorRenderer.getWarningsRendered(), getDisplayedWarnings());
175 moveListToMap(errorRenderer.getInfoRendered(), getDisplayedInfo());
176
177 errorRenderer.clear();
178 }
179
180
181
182
183
184
185 protected void moveListToMap(List<String> theList, Map theMap) {
186 for (String s : theList) {
187 theMap.put(s, "true");
188 }
189 }
190
191
192
193
194 protected GroupErrorsRenderer getErrorRenderer() {
195 return new GroupErrorsRenderer();
196 }
197
198
199
200
201
202
203
204 protected void renderAccountingLineContainers(PageContext pageContext, Tag parentTag) throws JspException {
205 for (AccountingLineRenderingContext container : containers) {
206 container.populateValuesForFields();
207 container.populateWithTabIndexIfRequested(arbitrarilyHighIndex);
208 container.renderElement(pageContext, parentTag, container);
209 }
210 }
211
212
213
214
215
216
217
218
219 protected void renderTotals(PageContext pageContext, Tag parentTag) throws JspException {
220 int cellCount = getWidthInCells();
221
222 List<? extends TotalDefinition> groupTotals = groupDefinition.getTotals();
223 for (TotalDefinition definition : groupTotals) {
224 if (definition instanceof NestedFieldTotaling) {
225 NestedFieldTotaling nestedFieldTotaling = (NestedFieldTotaling) definition;
226
227 if (nestedFieldTotaling.isNestedProperty()) {
228 int index = groupTotals.indexOf(definition);
229 AccountingLineRenderingContext container = this.containers.get(index);
230 String containingObjectPropertyName = container.getAccountingLineContainingObjectPropertyName();
231 nestedFieldTotaling.setContainingPropertyName(containingObjectPropertyName);
232 }
233 }
234
235 Renderer renderer = definition.getTotalRenderer();
236 if (renderer instanceof CellCountCurious) {
237 ((CellCountCurious) renderer).setCellCount(cellCount);
238 }
239
240 if (renderer instanceof RepresentedCellCurious) {
241 RepresentedCellCurious representedCellCurious = ((RepresentedCellCurious) renderer);
242 int columnNumberOfRepresentedCell = this.getRepresentedColumnNumber(representedCellCurious.getRepresentedCellPropertyName());
243 representedCellCurious.setColumnNumberOfRepresentedCell(columnNumberOfRepresentedCell);
244 }
245
246 if (renderer instanceof CollectionPropertiesCurious) {
247 ((CollectionPropertiesCurious)renderer).setCollectionProperty(this.collectionPropertyName);
248 ((CollectionPropertiesCurious)renderer).setCollectionItemProperty(this.collectionItemPropertyName);
249 }
250
251 renderer.render(pageContext, parentTag);
252 renderer.clear();
253 }
254 }
255
256
257
258
259
260
261
262 protected int getRepresentedColumnNumber(String propertyName) {
263 for (AccountingLineRenderingContext container : containers) {
264 List<AccountingLineTableRow> tableRows = container.getRows();
265
266 for (AccountingLineTableRow row : tableRows) {
267 List<AccountingLineTableCell> tableCells = row.getCells();
268 int cumulativeDisplayCellCount = 0;
269
270 for (AccountingLineTableCell cell : tableCells) {
271 cumulativeDisplayCellCount += cell.getColSpan();
272 List<RenderableElement> fields = cell.getRenderableElement();
273
274 for (RenderableElement field : fields) {
275 if (field instanceof ElementNamable == false) {
276 continue;
277 }
278
279 if (((ElementNamable) field).getName().equals(propertyName)) {
280 return cumulativeDisplayCellCount;
281 }
282 }
283 }
284 }
285 }
286
287 return -1;
288 }
289
290
291
292
293
294
295 public void setCellCount(int cellCount) {
296 this.cellCount = cellCount;
297 }
298
299
300
301
302
303
304 public void setImportLineOverride(JspFragment importLineOverride) {
305 this.importLineOverride = importLineOverride;
306 }
307
308
309
310
311
312
313 public void setArbitrarilyHighIndex(int arbitrarilyHighIndex) {
314 this.arbitrarilyHighIndex = arbitrarilyHighIndex;
315 }
316
317
318
319
320
321 public Map getDisplayedWarnings() {
322 return displayedWarnings;
323 }
324
325
326
327
328
329 public Map getDisplayedInfo() {
330 return displayedInfo;
331 }
332
333
334
335
336
337 public List getErrorKeys() {
338 return errorKeys;
339 }
340
341
342
343
344
345 public void setErrorKeys(List errorKeys) {
346 this.errorKeys = errorKeys;
347 }
348
349
350
351
352 private boolean isDocumentEnrouted() {
353 WorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
354
355 return !workflowDocument.isInitiated() && !workflowDocument.isSaved();
356 }
357
358
359
360
361 public void updateDeletabilityOfAllLines() {
362 if (this.isDocumentEnrouted()) {
363 if (hasEnoughAccountingLinesForDelete()) {
364 for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
365 if (accountingLineRenderingContext.isEditableLine()) {
366 accountingLineRenderingContext.makeDeletable();
367 }
368 }
369 }
370 } else {
371
372 for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
373 accountingLineRenderingContext.makeDeletable();
374 }
375 }
376 }
377
378
379
380
381
382 protected boolean hasEnoughAccountingLinesForDelete() {
383
384 int editableLineCount = 0;
385 for (AccountingLineRenderingContext accountingLineRenderingContext : containers) {
386 if (!accountingLineRenderingContext.isNewLine() && accountingLineRenderingContext.isEditableLine()) {
387 editableLineCount += 1;
388 }
389 if (editableLineCount == 2) return true;
390 }
391 return false;
392 }
393
394
395
396
397
398 public String getCollectionItemPropertyName() {
399 return collectionItemPropertyName;
400 }
401
402
403
404
405
406 public AccountingLineGroupDefinition getGroupDefinition() {
407 return groupDefinition;
408 }
409
410
411
412
413
414 public void setGroupDefinition(AccountingLineGroupDefinition groupDefinition) {
415 this.groupDefinition = groupDefinition;
416 }
417
418
419
420
421
422 public Map getDisplayedErrors() {
423 return displayedErrors;
424 }
425
426
427
428
429
430 public void setDisplayedErrors(Map displayedErrors) {
431 this.displayedErrors = displayedErrors;
432 }
433
434
435
436
437
438 public String getCollectionPropertyName() {
439 return collectionPropertyName;
440 }
441
442
443
444
445
446 public void setCollectionPropertyName(String collectionPropertyName) {
447 this.collectionPropertyName = collectionPropertyName;
448 }
449
450
451
452
453
454 public void setCollectionItemPropertyName(String collectionItemPropertyName) {
455 this.collectionItemPropertyName = collectionItemPropertyName;
456 }
457
458
459 public AccountingDocument getAccountingDocument() {
460 return accountingDocument;
461 }
462
463 public void setAccountingDocument(AccountingDocument accountingDocument) {
464 this.accountingDocument = accountingDocument;
465 }
466 }