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.module.ar.document.authorization;
017    
018    import java.util.Map;
019    import java.util.Set;
020    
021    import org.apache.commons.lang.StringUtils;
022    import org.kuali.kfs.fp.document.authorization.FinancialProcessingAccountingLineAuthorizer;
023    import org.kuali.kfs.module.ar.ArConstants;
024    import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
025    import org.kuali.kfs.sys.businessobject.AccountingLine;
026    import org.kuali.kfs.sys.context.SpringContext;
027    import org.kuali.kfs.sys.document.AccountingDocument;
028    import org.kuali.kfs.sys.document.web.AccountingLineRenderingContext;
029    import org.kuali.kfs.sys.document.web.AccountingLineViewAction;
030    import org.kuali.rice.kim.bo.Person;
031    import org.kuali.rice.kns.document.Document;
032    import org.kuali.rice.kns.service.KualiConfigurationService;
033    import org.kuali.rice.kns.service.ParameterService;
034    
035    public class CustomerInvoiceDocumentSourceLinesAuthorizer extends FinancialProcessingAccountingLineAuthorizer {
036    
037        private static final String RECALCULATE_METHOD_NAME = "recalculateSourceLine";
038        private static final String RECALCULATE_LABEL = "Recalculate Source Accounting Line";
039        private static final String RECALCULATE_BUTTON_IMAGE = "tinybutton-recalculate.gif";
040        private static final String DISCOUNT_METHOD_NAME = "discountSourceLine";
041        private static final String DISCOUNT_LABEL = "Discount a Source Accounting Line";
042        private static final String DISCOUNT_BUTTON_IMAGE = "tinybutton-discount.gif";
043        private static final String REFRESH_METHOD_NAME = "refreshNewSourceLine";
044        private static final String REFRESH_LABEL = "Refresh New Source Line";
045        private static final String REFRESH_BUTTON_IMAGE = "tinybutton-refresh.gif";
046    
047        /**
048         * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizerBase#getActionMap(org.kuali.kfs.sys.businessobject.AccountingLine,
049         *      java.lang.String, java.lang.Integer, java.lang.String)
050         */
051        @Override
052        protected Map<String, AccountingLineViewAction> getActionMap(AccountingLineRenderingContext accountingLineRenderingContext, String accountingLinePropertyName, Integer accountingLineIndex, String groupTitle) {
053            Map<String, AccountingLineViewAction> actionMap = super.getActionMap(accountingLineRenderingContext, accountingLinePropertyName, accountingLineIndex, groupTitle);
054    
055            CustomerInvoiceDetail invoiceLine = (CustomerInvoiceDetail) accountingLineRenderingContext.getAccountingLine();
056    
057            // get the images base directory
058            String kfsImagesPath = SpringContext.getBean(KualiConfigurationService.class).getPropertyString("externalizable.images.url");
059    
060            // show the Refresh button on the New Line Actions
061            if (isNewLine(accountingLineIndex)) {
062                actionMap.put(REFRESH_METHOD_NAME, new AccountingLineViewAction(REFRESH_METHOD_NAME, REFRESH_LABEL, kfsImagesPath + REFRESH_BUTTON_IMAGE));
063            }
064            else {
065                // always add the Recalculate button if its in edit mode
066                String groupName = super.getActionInfixForExtantAccountingLine(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName);
067                String methodName = methodName(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, RECALCULATE_METHOD_NAME);
068                actionMap.put(methodName, new AccountingLineViewAction(methodName, RECALCULATE_LABEL, kfsImagesPath + RECALCULATE_BUTTON_IMAGE));
069    
070                // only add the Discount button if its not a Discount Line or a Discount Line Parent
071                if (showDiscountButton(invoiceLine)) {
072                    methodName = methodName(accountingLineRenderingContext.getAccountingLine(), accountingLinePropertyName, accountingLineIndex, DISCOUNT_METHOD_NAME);
073                    actionMap.put(methodName, new AccountingLineViewAction(methodName, DISCOUNT_LABEL, kfsImagesPath + DISCOUNT_BUTTON_IMAGE));
074                }
075            }
076    
077            return actionMap;
078        }
079    
080        private boolean showDiscountButton(CustomerInvoiceDetail invoiceLine) {
081            return (!invoiceLine.isDiscountLine() && !invoiceLine.isDiscountLineParent());
082        }
083    
084        private String methodName(AccountingLine line, String accountingLineProperty, Integer accountingLineIndex, String methodName) {
085            String infix = super.getActionInfixForExtantAccountingLine(line, accountingLineProperty);
086            return methodName + ".line" + accountingLineIndex.toString() + ".anchoraccounting" + infix + "Anchor";
087        }
088    
089        private boolean isNewLine(Integer accountingLineIndex) {
090            return (accountingLineIndex == null || accountingLineIndex.intValue() < 0);
091        }
092        
093        @Override
094        public Set<String> getUnviewableBlocks(AccountingDocument accountingDocument, AccountingLine accountingLine, boolean newLine, Person currentUser) {
095            Set<String> blocks = super.getUnviewableBlocks(accountingDocument, accountingLine, newLine, currentUser);
096            ParameterService parameterService = SpringContext.getBean(ParameterService.class);
097            boolean enableTax = parameterService.getIndicatorParameter("KFS-AR", "Document", ArConstants.ENABLE_SALES_TAX_IND);
098            if (!enableTax) {
099                blocks.add("invoiceItemTaxAmount");
100                blocks.add("taxableIndicator");
101            }
102            return blocks;
103        }
104        
105        /**
106         * Overridden to make:
107         * 1. chart and account number read only for discount lines
108         * 2. invoice item description and amount editable for recurring invoices
109         * 
110         * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizerBase#determineFieldModifyability(org.kuali.kfs.sys.document.AccountingDocument,
111         *      org.kuali.kfs.sys.businessobject.AccountingLine, org.kuali.kfs.sys.document.web.AccountingLineViewField, java.util.Map)
112         */
113        @Override
114        public boolean determineEditPermissionOnField(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, String fieldName, boolean editablePage) {
115            boolean canModify = super.determineEditPermissionOnField(accountingDocument, accountingLine, accountingLineCollectionProperty, fieldName, editablePage);
116            
117            if (canModify) {
118                boolean discountLineFlag = ((CustomerInvoiceDetail)accountingLine).isDiscountLine();
119                if (discountLineFlag) {
120                    if (StringUtils.equals(fieldName, getChartPropertyName()) || StringUtils.equals(fieldName, getAccountNumberPropertyName())) 
121                        canModify = false;
122                }
123            }
124            
125            return canModify;
126        }
127    
128        /**
129         * @return the property name of the chart field, which will be set to read only for discount lines
130         */
131        protected String getChartPropertyName() {
132            return "chartOfAccountsCode";
133        }
134    
135        /**
136         * @return the property name of the account number field, which will be set to read only for discount lines
137         */
138        protected String getAccountNumberPropertyName() {
139            return "accountNumber";
140        }
141        
142        /**
143         * @return the property name of the invoice item description field, which will be set editable for recurring invoices
144         */
145        protected String getItemDescriptionPropertyName() {
146            return "invoiceItemDescription";
147        }
148        
149        /**
150         * @return the property name of the amount field, which will be set editable for recurring invoices
151         */
152        protected String getAmountPropertyName() {
153            return "amount";
154        }
155    }