001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.document.web;
017    
018    import java.util.List;
019    import java.util.Map;
020    import java.util.Set;
021    
022    import org.kuali.kfs.sys.KFSPropertyConstants;
023    import org.kuali.kfs.sys.businessobject.AccountingLine;
024    import org.kuali.kfs.sys.context.SpringContext;
025    import org.kuali.kfs.sys.document.AccountingDocument;
026    import org.kuali.kfs.sys.document.datadictionary.AccountingLineViewDebitCreditAmountFieldDefinition;
027    import org.kuali.kfs.sys.document.datadictionary.AccountingLineViewFieldDefinition;
028    import org.kuali.kfs.sys.document.service.AccountingLineFieldRenderingTransformation;
029    import org.kuali.rice.kns.service.KualiConfigurationService;
030    import org.kuali.rice.kns.web.ui.Field;
031    
032    /**
033     * A table joining element which adds two fields to an amount: debit amount and credit amount
034     */
035    public class AccountingLineViewDebitCreditAmountLayoutElement implements TableJoiningWithHeader, ReadOnlyable {
036        private Field debitAmountField;
037        private Field creditAmountField;
038        private AccountingLineViewDebitCreditAmountFieldDefinition definition;
039        private AccountingLineViewFieldDefinition debitFieldDefinition;
040        private AccountingLineViewFieldDefinition creditFieldDefinition;
041        
042        /**
043         * Returns whether the debit and the credit amount fields are both read only 
044         * @see org.kuali.kfs.sys.document.web.ReadOnlyable#isReadOnly()
045         */
046        public boolean isReadOnly() {
047            return (debitAmountField == null || debitAmountField.isReadOnly()) && (creditAmountField == null || creditAmountField.isReadOnly());
048        }
049        
050        /**
051         * Read onlyizes both the credit and the debit amount fields
052         * @see org.kuali.kfs.sys.document.web.ReadOnlyable#readOnlyize()
053         */
054        public void readOnlyize() {
055            if (debitAmountField != null) {
056                debitAmountField.setReadOnly(true);
057            }
058            if (creditAmountField != null) {
059                creditAmountField.setReadOnly(true);
060            }
061        }
062        
063        /**
064         * We don't generate headers
065         * @see org.kuali.kfs.sys.document.web.TableJoiningWithHeader#createHeaderLabel()
066         */
067        public HeaderLabel createHeaderLabel() {
068            return null;
069        }
070        
071        /**
072         * This isn't hidden
073         * @see org.kuali.kfs.sys.document.web.TableJoiningWithHeader#isHidden()
074         */
075        public boolean isHidden() {
076            return false;
077        }
078        
079        /**
080         * This renderable element...it ain't got no single name! 
081         * @see org.kuali.kfs.sys.document.web.TableJoining#getName()
082         */
083        public String getName() {
084            return null;
085        }
086        
087        /**
088         * Request two rows - one for the header, one for the field
089         * @see org.kuali.kfs.sys.document.web.TableJoining#getRequestedRowCount()
090         */
091        public int getRequestedRowCount() {
092            return 2;
093        }
094        
095        /**
096         * @see org.kuali.kfs.sys.document.web.TableJoining#joinRow(org.kuali.kfs.sys.document.web.AccountingLineTableRow, org.kuali.kfs.sys.document.web.AccountingLineTableRow)
097         */
098        public void joinRow(AccountingLineTableRow headerLabelRow, AccountingLineTableRow row) {
099            if (debitAmountField != null) {
100                headerLabelRow.addCell(createHeaderCellForField(true));
101                row.addCell(createCellForField(debitAmountField, debitFieldDefinition, true));
102            }
103            if (creditAmountField != null) {
104                headerLabelRow.addCell(createHeaderCellForField(false));
105                row.addCell(createCellForField(creditAmountField, creditFieldDefinition, false));
106            }
107        }
108        
109        /**
110         * @see org.kuali.kfs.sys.document.web.TableJoining#joinTable(java.util.List)
111         */
112        public void joinTable(List<AccountingLineTableRow> rows) {
113            final int remainingRowCount = rows.size() - 1;
114            
115            if (debitAmountField != null) {
116                rows.get(0).addCell(createHeaderCellForField(true));
117                
118                AccountingLineTableCell currentCell = createCellForField(debitAmountField, debitFieldDefinition, true);
119                currentCell.setRowSpan(remainingRowCount);
120                rows.get(1).addCell(currentCell);
121            }
122            if (creditAmountField != null) {
123                rows.get(0).addCell(createHeaderCellForField(false));
124                
125                AccountingLineTableCell baseCell = createCellForField(creditAmountField, creditFieldDefinition, false);
126                baseCell.setRowSpan(remainingRowCount);
127                rows.get(1).addCell(baseCell);
128            }
129        }
130        
131        /**
132         * Creates a table cell with a renderable field inside
133         * @param field the field to create a cell for
134         * @return a cell that wraps the given field 
135         */
136        protected AccountingLineTableCell createCellForField(Field field, AccountingLineViewFieldDefinition definition, boolean isDebit) {
137            AccountingLineTableCell cell = new AccountingLineTableCell();
138            AccountingLineViewDebitCreditAmountField renderableField = new AccountingLineViewDebitCreditAmountField(field, definition, isDebit, (isDebit ? this.definition.getNewLineDebitAmountProperty() : this.definition.getNewLineCreditAmountProperty()), this.definition.getVoucherLineHelperProperty());
139            cell.addRenderableElement(renderableField);
140            return cell;
141        }
142        
143        /**
144         * Creates a header cell for the given field
145         * @param field the field to create a header cell for
146         * @return a header cell
147         */
148        protected AccountingLineTableCell createHeaderCellForField(boolean isDebit) {
149            AccountingLineTableCell headerCell = new AccountingLineTableCell();
150            headerCell.setRendersAsHeader(true);
151            final String propertyName = isDebit ? getDebitPropertyName() : getCreditPropertyName();
152            final String label = SpringContext.getBean(KualiConfigurationService.class).getPropertyString(propertyName); 
153            headerCell.addRenderableElement(new LiteralHeaderLabel(label));
154            return headerCell;
155        }
156        
157        /**
158         * @return the property name for debit labels
159         */
160        protected String getDebitPropertyName() {
161            return "label.document.journalVoucher.accountingLine.debit";
162        }
163        
164        /**
165         * @return the property name for credit labels
166         */
167        protected String getCreditPropertyName() {
168            return "label.document.journalVoucher.accountingLine.credit";
169        }
170        
171        /**
172         * @see org.kuali.kfs.sys.document.web.TableJoining#performFieldTransformations(java.util.List, org.kuali.kfs.sys.businessobject.AccountingLine, java.util.Map, java.util.Map)
173         */
174        public void performFieldTransformations(List<AccountingLineFieldRenderingTransformation> fieldTransformations, AccountingLine accountingLine, Map unconvertedValues) {
175            for (AccountingLineFieldRenderingTransformation fieldTransformation : fieldTransformations) {
176                fieldTransformation.transformField(accountingLine, getDebitAmountField(), getDebitFieldDefinition(), unconvertedValues);
177                fieldTransformation.transformField(accountingLine, getCreditAmountField(), getCreditFieldDefinition(), unconvertedValues);
178            }
179        }
180        
181        /**
182         * @see org.kuali.kfs.sys.document.web.TableJoining#readOnlyizeReadOnlyBlocks(java.util.Set)
183         */
184        public void readOnlyizeReadOnlyBlocks(Set<String> readOnlyBlocks) {
185            if (readOnlyBlocks.contains(KFSPropertyConstants.AMOUNT)) {
186                if (debitAmountField != null) {
187                    debitAmountField.setReadOnly(true);
188                }
189                if (creditAmountField != null) {
190                    creditAmountField.setReadOnly(true);
191                }
192            }
193        }
194        
195        /**
196         * Does nothing - we don't have action blocks, like, ever
197         * @see org.kuali.kfs.sys.document.web.TableJoining#removeAllActionBlocks()
198         */
199        public void removeAllActionBlocks() {}
200        
201        /**
202         * @see org.kuali.kfs.sys.document.web.TableJoining#removeUnviewableBlocks(java.util.Set)
203         */
204        public void removeUnviewableBlocks(Set<String> unviewableBlocks) {
205            if (unviewableBlocks.contains(KFSPropertyConstants.AMOUNT)) {
206                if (debitAmountField != null) {
207                    debitAmountField = null;
208                }
209                if (creditAmountField != null) {
210                    creditAmountField = null;
211                }
212            }
213        }
214        
215        /**
216         * Gets the creditAmountField attribute. 
217         * @return Returns the creditAmountField.
218         */
219        public Field getCreditAmountField() {
220            return creditAmountField;
221        }
222        /**
223         * Sets the creditAmountField attribute value.
224         * @param creditAmountField The creditAmountField to set.
225         */
226        public void setCreditAmountField(Field creditAmountField) {
227            this.creditAmountField = creditAmountField;
228        }
229        /**
230         * Gets the creditFieldDefinition attribute. 
231         * @return Returns the creditFieldDefinition.
232         */
233        public AccountingLineViewFieldDefinition getCreditFieldDefinition() {
234            return creditFieldDefinition;
235        }
236        /**
237         * Sets the creditFieldDefinition attribute value.
238         * @param creditFieldDefinition The creditFieldDefinition to set.
239         */
240        public void setCreditFieldDefinition(AccountingLineViewFieldDefinition creditFieldDefinition) {
241            this.creditFieldDefinition = creditFieldDefinition;
242        }
243        /**
244         * Gets the debitAmountField attribute. 
245         * @return Returns the debitAmountField.
246         */
247        public Field getDebitAmountField() {
248            return debitAmountField;
249        }
250        /**
251         * Sets the debitAmountField attribute value.
252         * @param debitAmountField The debitAmountField to set.
253         */
254        public void setDebitAmountField(Field debitAmountField) {
255            this.debitAmountField = debitAmountField;
256        }
257        /**
258         * Gets the debitFieldDefinition attribute. 
259         * @return Returns the debitFieldDefinition.
260         */
261        public AccountingLineViewFieldDefinition getDebitFieldDefinition() {
262            return debitFieldDefinition;
263        }
264        /**
265         * Sets the debitFieldDefinition attribute value.
266         * @param debitFieldDefinition The debitFieldDefinition to set.
267         */
268        public void setDebitFieldDefinition(AccountingLineViewFieldDefinition debitFieldDefinition) {
269            this.debitFieldDefinition = debitFieldDefinition;
270        }
271        /**
272         * Gets the definition attribute. 
273         * @return Returns the definition.
274         */
275        public AccountingLineViewDebitCreditAmountFieldDefinition getDefinition() {
276            return definition;
277        }
278        /**
279         * Sets the definition attribute value.
280         * @param definition The definition to set.
281         */
282        public void setDefinition(AccountingLineViewDebitCreditAmountFieldDefinition definition) {
283            this.definition = definition;
284        }
285    
286        /**
287         * @see org.kuali.kfs.sys.document.web.TableJoining#setEditableBlocks(java.util.Set)
288         */
289        public void setEditableBlocks(Set<String> editableBlocks) {
290            if (editableBlocks.contains(KFSPropertyConstants.AMOUNT)) {
291                if (debitAmountField != null) {
292                    debitAmountField.setReadOnly(false);
293                }
294                if (creditAmountField != null) {
295                    creditAmountField.setReadOnly(false);
296                }
297            }
298        }
299    
300        /**
301         * @see org.kuali.kfs.sys.document.web.ReadOnlyable#setEditable()
302         */
303        public void setEditable() {
304            if (debitAmountField != null) {
305                debitAmountField.setReadOnly(false);
306            }
307            
308            if (creditAmountField != null) {
309                creditAmountField.setReadOnly(false);
310            }
311        }
312    }