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.purap.document.authorization;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.kfs.module.purap.PurapConstants;
020    import org.kuali.kfs.module.purap.PurapPropertyConstants;
021    import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine;
022    import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
023    import org.kuali.kfs.module.purap.document.PurchaseOrderAmendmentDocument;
024    import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
025    import org.kuali.kfs.sys.businessobject.AccountingLine;
026    import org.kuali.kfs.sys.document.AccountingDocument;
027    import org.kuali.rice.kns.util.KualiDecimal;
028    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
029    
030    /**
031     * Accounting line authorizer for Requisition document which allows adding accounting lines at specified nodes
032     */
033    public class PurchaseOrderAccountingLineAuthorizer extends PurapAccountingLineAuthorizer {
034        private static final String NEW_UNORDERED_ITEMS_NODE = "NewUnorderedItems";
035    
036        /**
037         * Allow new lines to be rendered at NewUnorderedItems node
038         * @see org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizerBase#renderNewLine(org.kuali.kfs.sys.document.AccountingDocument, java.lang.String)
039         */
040        @Override
041        public boolean renderNewLine(AccountingDocument accountingDocument, String accountingGroupProperty) {
042            KualiWorkflowDocument workflowDoc = accountingDocument.getDocumentHeader().getWorkflowDocument();
043            String currentRouteNodeName = workflowDoc.getCurrentRouteNodeNames();
044            
045            //  if its in the NEW_UNORDERED_ITEMS node, then allow the new line to be drawn
046            if (PurchaseOrderAccountingLineAuthorizer.NEW_UNORDERED_ITEMS_NODE.equals(currentRouteNodeName)) {
047                return true;
048            }
049            
050            if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT.equals(workflowDoc.getDocumentType()) && StringUtils.isNotBlank(accountingGroupProperty) && accountingGroupProperty.contains(PurapPropertyConstants.ITEM)) {
051                int itemNumber = determineItemNumberFromGroupProperty(accountingGroupProperty);
052                PurchaseOrderAmendmentDocument poaDoc = (PurchaseOrderAmendmentDocument) accountingDocument;
053                PurchaseOrderItem item = (PurchaseOrderItem) poaDoc.getItem(itemNumber);
054                return item.isNewItemForAmendment() || item.getSourceAccountingLines().size() == 0;
055            }
056            
057            return super.renderNewLine(accountingDocument, accountingGroupProperty);
058        }
059        
060        private int determineItemNumberFromGroupProperty(String accountingGroupProperty) {
061            int openBracketPos = accountingGroupProperty.indexOf("[");
062            int closeBracketPos = accountingGroupProperty.indexOf("]");
063            String itemNumberString = accountingGroupProperty.substring(openBracketPos + 1, closeBracketPos);
064            int itemNumber = new Integer(itemNumberString).intValue();
065            return itemNumber;
066        }
067        
068        @Override
069        protected boolean allowAccountingLinesAreEditable(AccountingDocument accountingDocument,
070                AccountingLine accountingLine){
071            PurApAccountingLine purapAccount = (PurApAccountingLine)accountingLine;
072            PurchaseOrderItem poItem = (PurchaseOrderItem)purapAccount.getPurapItem();
073            PurchaseOrderDocument po = (PurchaseOrderDocument)accountingDocument;
074            
075            
076            if (poItem != null && !poItem.getItemType().isAdditionalChargeIndicator()) {
077                if (!poItem.isItemActiveIndicator()) {
078                    return false;
079                }
080    
081                // if total amount has a value and is non-zero
082                if (poItem.getItemInvoicedTotalAmount() != null && poItem.getItemInvoicedTotalAmount().compareTo(new KualiDecimal(0)) != 0) {
083                    return false;
084                }
085                
086                if (po.getContainsUnpaidPaymentRequestsOrCreditMemos() && !poItem.isNewItemForAmendment()) {
087                    return false;
088                }
089                
090            }
091            return super.allowAccountingLinesAreEditable(accountingDocument, accountingLine);
092        }
093    
094        @Override
095        public boolean determineEditPermissionOnLine(AccountingDocument accountingDocument, AccountingLine accountingLine, String accountingLineCollectionProperty, boolean currentUserIsDocumentInitiator, boolean pageIsEditable) {
096         // the fields in a new line should be always editable
097            if (accountingLine.getSequenceNumber() == null) {
098                return true;
099            }
100            
101            // check the initiation permission on the document if it is in the state of preroute, but only if
102            // the PO status is not In Process.
103            KualiWorkflowDocument workflowDocument = accountingDocument.getDocumentHeader().getWorkflowDocument();
104            PurchaseOrderDocument poDocument = (PurchaseOrderDocument)accountingDocument;
105            if (!poDocument.getStatusCode().equals(PurapConstants.PurchaseOrderStatuses.IN_PROCESS) && (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved())) {
106                if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_AMENDMENT_DOCUMENT.equals(workflowDocument.getDocumentType())) {
107                    PurApAccountingLine purapAccount = (PurApAccountingLine)accountingLine;
108                    PurchaseOrderItem item = (PurchaseOrderItem)purapAccount.getPurapItem();
109                    return item.isNewItemForAmendment() || item.getSourceAccountingLines().size() == 0;
110                }
111                else {
112                    return currentUserIsDocumentInitiator;
113                }
114            }
115            else {
116                return true;
117            }
118        }
119        
120    }