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.fp.document.web.struts;
017    
018    import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DISPUTE_URL_PARM_NM;
019    
020    import java.util.ArrayList;
021    import java.util.Iterator;
022    import java.util.List;
023    import java.util.Map;
024    
025    import javax.servlet.http.HttpServletRequest;
026    
027    import org.apache.commons.lang.StringUtils;
028    import org.kuali.kfs.fp.businessobject.CapitalAssetInformation;
029    import org.kuali.kfs.fp.businessobject.ProcurementCardTargetAccountingLine;
030    import org.kuali.kfs.fp.businessobject.ProcurementCardTransactionDetail;
031    import org.kuali.kfs.fp.document.CapitalAssetEditable;
032    import org.kuali.kfs.fp.document.ProcurementCardDocument;
033    import org.kuali.kfs.sys.KFSConstants;
034    import org.kuali.kfs.sys.KFSPropertyConstants;
035    import org.kuali.kfs.sys.businessobject.TargetAccountingLine;
036    import org.kuali.kfs.sys.context.SpringContext;
037    import org.kuali.kfs.sys.document.authorization.AccountingLineAuthorizer;
038    import org.kuali.kfs.sys.document.datadictionary.AccountingLineGroupDefinition;
039    import org.kuali.kfs.sys.document.datadictionary.FinancialSystemTransactionalDocumentEntry;
040    import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase;
041    import org.kuali.rice.kim.bo.Person;
042    import org.kuali.rice.kns.datadictionary.DataDictionary;
043    import org.kuali.rice.kns.service.DataDictionaryService;
044    import org.kuali.rice.kns.service.ParameterService;
045    import org.kuali.rice.kns.util.GlobalVariables;
046    import org.kuali.rice.kns.util.KNSConstants;
047    import org.kuali.rice.kns.util.TypedArrayList;
048    
049    /**
050     * This class is the form class for the ProcurementCard document. This method extends the parent KualiTransactionalDocumentFormBase
051     * class which contains all of the common form methods and form attributes needed by the Procurment Card document.
052     */
053    public class ProcurementCardForm extends KualiAccountingDocumentFormBase implements CapitalAssetEditable{
054        protected static final long serialVersionUID = 1L;
055        protected List newTargetLines;
056        protected List<Boolean> transactionCreditCardNumbersViewStatus;
057        protected final static String TARGET_ACCOUNTING_LINE_GROUP_NAME = "target";
058        
059        protected CapitalAssetInformation capitalAssetInformation;
060    
061        /**
062         * Override to accomodate multiple target lines.
063         * 
064         * @see org.kuali.rice.kns.web.struts.pojo.PojoForm#populate(javax.servlet.http.HttpServletRequest)
065         */
066        @Override
067        public void populate(HttpServletRequest request) {
068            super.populate(request);
069    
070            //
071            // now run through all of the accounting lines and make sure they've been uppercased and populated appropriately
072    
073            // handle new accountingLine, if one is being added
074            final String methodToCall = this.getMethodToCall();
075            final Map parameterMap = request.getParameterMap();
076            if (StringUtils.isNotBlank(methodToCall)) {
077                if (methodToCall.equals(KFSConstants.INSERT_SOURCE_LINE_METHOD)) {
078                    populateSourceAccountingLine(getNewSourceLine(), KFSPropertyConstants.NEW_SOURCE_LINE, parameterMap);
079                }
080    
081                if (methodToCall.equals(KFSConstants.INSERT_TARGET_LINE_METHOD)) {
082                    // This is the addition for the override: Handle multiple accounting lines ...
083                    for (Iterator newTargetLinesIter = getNewTargetLines().iterator(); newTargetLinesIter.hasNext();) {
084                        TargetAccountingLine targetAccountingLine = (TargetAccountingLine) newTargetLinesIter.next();
085                        populateTargetAccountingLine(targetAccountingLine, KFSPropertyConstants.NEW_TARGET_LINE, parameterMap);
086                    }
087                }
088            }
089    
090            // don't call populateAccountingLines if you are copying or errorCorrecting a document,
091            // since you want the accountingLines in the copy to be "identical" to those in the original
092            if (!StringUtils.equals(methodToCall, KFSConstants.COPY_METHOD) && !StringUtils.equals(methodToCall, KFSConstants.ERRORCORRECT_METHOD)) {
093                populateAccountingLines(parameterMap);
094            }
095    
096            setDocTypeName(discoverDocumentTypeName());
097        }
098    
099        /**
100         * Constructs a ProcurmentCardForm instance and sets up the appropriately casted document. Also, the newSourceLine needs to be
101         * the extended ProcurementCardSourceAccountingLine, for the additional trans line nbr.
102         */
103        public ProcurementCardForm() {
104            super();
105            this.newTargetLines = new TypedArrayList(ProcurementCardTargetAccountingLine.class);
106            this.setCapitalAssetInformation(new CapitalAssetInformation());
107        }
108    
109        @Override
110        protected String getDefaultDocumentTypeName() {
111            return "PCDO";
112        }
113        
114        /**
115         * @return The retreived APC string used for the dispute url.
116         */
117        public String getDisputeURL() {
118            return SpringContext.getBean(ParameterService.class).getParameterValue(ProcurementCardDocument.class, DISPUTE_URL_PARM_NM);
119        }
120    
121    
122        /**
123         * @return Returns the newTargetLines.
124         */
125        public List getNewTargetLines() {
126            return newTargetLines;
127        }
128    
129        /**
130         * @param newTargetLines The newTargetLines to set.
131         */
132        public void setNewTargetLines(List newTargetLines) {
133            this.newTargetLines = newTargetLines;
134        }
135        
136        /**
137         * @see org.kuali.kfs.fp.document.CapitalAssetEditable#getCapitalAssetInformation()
138         */
139        public CapitalAssetInformation getCapitalAssetInformation() {
140            return this.capitalAssetInformation;
141        }
142    
143        /**
144         * @see org.kuali.kfs.fp.document.CapitalAssetEditable#setCapitalAssetInformation(org.kuali.kfs.fp.businessobject.CapitalAssetInformation)
145         */
146        public void setCapitalAssetInformation(CapitalAssetInformation capitalAssetInformation) {
147            this.capitalAssetInformation = capitalAssetInformation;        
148        }
149        
150        /**
151         * @return an array, parallel to the ProcurementCardDocument#getTransactionEntries, which holds whether the
152         * current user can see the credit card number or not
153         */
154        public List<Boolean> getTransactionCreditCardNumbersViewStatus() {
155            if (this.transactionCreditCardNumbersViewStatus == null) {
156                populateTransactionCreditCardNumbersViewStatuses();
157            }
158            return transactionCreditCardNumbersViewStatus;
159        }
160        
161        /**
162         * populates an array, parallel to the ProcurementCardDocument#getTransactionEntries, which holds whether the
163         * current user can see the credit card number or not - based on if any of the accounting lines are editable to
164         * the user or not...
165         */
166        protected void populateTransactionCreditCardNumbersViewStatuses() {
167            final AccountingLineAuthorizer accountingLineAuthorizer = getAccountingLineAuthorizerForDocument();
168            final Person currentUser = GlobalVariables.getUserSession().getPerson();
169            transactionCreditCardNumbersViewStatus = new ArrayList<Boolean>();
170            
171            for (Object transactionEntryAsObject : ((ProcurementCardDocument)getDocument()).getTransactionEntries()) {
172                final ProcurementCardTransactionDetail transactionDetail = (ProcurementCardTransactionDetail)transactionEntryAsObject;
173                Boolean canEditAnyAccountingLine = Boolean.FALSE;
174                    
175                int count = 0;
176                while (!canEditAnyAccountingLine.booleanValue() && count < transactionDetail.getTargetAccountingLines().size()) {
177                    final TargetAccountingLine accountingLine = (TargetAccountingLine)transactionDetail.getTargetAccountingLines().get(count);
178                    if (accountingLineAuthorizer.hasEditPermissionOnAccountingLine(((ProcurementCardDocument)getDocument()), accountingLine, getAccountingLineCollectionName(), currentUser, getDocumentActions().containsKey(KNSConstants.KUALI_ACTION_CAN_EDIT))) {
179                        canEditAnyAccountingLine = Boolean.TRUE;
180                    }
181                    count += 1;
182                }
183                transactionCreditCardNumbersViewStatus.add(canEditAnyAccountingLine);
184            }
185        }
186        
187        /**
188         * @return the accounting line authorizer for the target lines of this document
189         */
190        protected AccountingLineAuthorizer getAccountingLineAuthorizerForDocument() {
191            final DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
192            final DataDictionary dataDictionary = dataDictionaryService.getDataDictionary();
193            final String documentTypeCode = dataDictionaryService.getDocumentTypeNameByClass(this.getDocument().getClass());
194            final FinancialSystemTransactionalDocumentEntry documentEntry = (FinancialSystemTransactionalDocumentEntry)dataDictionary.getDocumentEntry(documentTypeCode);
195            final AccountingLineGroupDefinition targetAccountingLineGroupDefinition = documentEntry.getAccountingLineGroups().get(ProcurementCardForm.TARGET_ACCOUNTING_LINE_GROUP_NAME);
196            return targetAccountingLineGroupDefinition.getAccountingLineAuthorizer();
197        }
198        
199        /**
200         * @return the name of the accounting line collection for the permission check
201         */
202        protected String getAccountingLineCollectionName() {
203            // we'll just cheat...
204            return "targetAccountingLines";
205        }
206    }