View Javadoc
1   /*
2    * Copyright 2013 The Kuali Foundation.
3    *
4    * Licensed under the Educational Community License, Version 1.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl1.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.select.document.web.struts;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.struts.action.ActionForm;
20  import org.apache.struts.action.ActionForward;
21  import org.apache.struts.action.ActionMapping;
22  import org.kuali.ole.fp.document.DisbursementVoucherConstants;
23  import org.kuali.ole.fp.document.DisbursementVoucherDocument;
24  import org.kuali.ole.fp.document.web.struts.DisbursementVoucherAction;
25  import org.kuali.ole.fp.document.web.struts.DisbursementVoucherForm;
26  import org.kuali.ole.module.purap.PurapConstants;
27  import org.kuali.ole.module.purap.service.PurapAccountingService;
28  import org.kuali.ole.select.businessobject.OleDisbursementVoucherAccountingLine;
29  import org.kuali.ole.select.document.OleDisbursementVoucherDocument;
30  import org.kuali.ole.select.document.validation.event.OleDisbursementAccountPercentEvent;
31  import org.kuali.ole.sys.OLEConstants;
32  import org.kuali.ole.sys.OLEKeyConstants;
33  import org.kuali.ole.sys.OLEPropertyConstants;
34  import org.kuali.ole.sys.businessobject.SourceAccountingLine;
35  import org.kuali.ole.sys.context.SpringContext;
36  import org.kuali.ole.sys.web.struts.KualiAccountingDocumentFormBase;
37  import org.kuali.ole.vnd.businessobject.VendorAddress;
38  import org.kuali.ole.vnd.businessobject.VendorAlias;
39  import org.kuali.ole.vnd.businessobject.VendorDetail;
40  import org.kuali.rice.core.api.util.type.KualiDecimal;
41  import org.kuali.rice.krad.service.BusinessObjectService;
42  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
43  import org.kuali.rice.krad.service.KualiRuleService;
44  import org.kuali.rice.krad.service.LookupService;
45  import org.kuali.rice.krad.util.GlobalVariables;
46  import org.kuali.rice.krad.util.ObjectUtils;
47  
48  import javax.servlet.http.HttpServletRequest;
49  import javax.servlet.http.HttpServletResponse;
50  import java.math.BigDecimal;
51  import java.math.RoundingMode;
52  import java.util.HashMap;
53  import java.util.List;
54  import java.util.Map;
55  
56  public class OleDisbursementVoucherAction extends DisbursementVoucherAction {
57  
58      private PurapAccountingService purapAccountingService;
59  
60      /**
61       * This action executes an insert of a SourceAccountingLine into a document only after validating the accounting line and
62       * checking any appropriate business rules.
63       *
64       * @param mapping
65       * @param form
66       * @param request
67       * @param response
68       * @return ActionForward
69       * @throws Exception
70       */
71      @Override
72      public ActionForward insertSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
73          OleDisbursementVoucherForm disbursementVoucherForm = (OleDisbursementVoucherForm) form;
74          OleDisbursementVoucherDocument disbursementDocument = disbursementVoucherForm.getDisbursementVoucherDocument();
75          OleDisbursementVoucherAccountingLine line = (OleDisbursementVoucherAccountingLine) disbursementVoucherForm.getNewSourceLine();
76          KualiDecimal totalAmount = disbursementDocument.getDisbVchrCheckTotalAmount();
77          if ((totalAmount != null) && KualiDecimal.ZERO.compareTo(totalAmount) != 0) {
78              if (ObjectUtils.isNotNull(line.getAccountLinePercent())) {
79                  BigDecimal pct = new BigDecimal(line.getAccountLinePercent().toString()).divide(new BigDecimal(100));
80                  line.setAmount(new KualiDecimal(pct.multiply(new BigDecimal(totalAmount.toString())).setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR)));
81              } else if (ObjectUtils.isNotNull(line.getAmount()) && ObjectUtils.isNull(line.getAccountLinePercent())) {
82                  KualiDecimal dollar = line.getAmount().multiply(new KualiDecimal(100));
83                  BigDecimal dollarToPercent = dollar.bigDecimalValue().divide((totalAmount.bigDecimalValue()), 0, RoundingMode.FLOOR);
84                  line.setAccountLinePercent(dollarToPercent);
85              }
86          }
87          return super.insertSourceLine(mapping, disbursementVoucherForm, request, response);
88      }
89  
90      /**
91       * This method routes the Disbursement Document.
92       *
93       * @param mapping
94       * @param form
95       * @param request
96       * @param response
97       * @return ActionForward
98       * @throws Exception
99       * @see org.kuali.ole.sys.web.struts.KualiAccountingDocumentActionBase#route(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
100      */
101     @Override
102     public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
103         OleDisbursementVoucherForm disbursementVoucherForm = (OleDisbursementVoucherForm) form;
104         OleDisbursementVoucherDocument disbursementDocument = disbursementVoucherForm.getDisbursementVoucherDocument();
105         boolean isValid = true;
106         ActionForward forward = mapping.findForward(OLEConstants.MAPPING_BASIC);
107         boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new OleDisbursementAccountPercentEvent(OLEConstants.ACCOUNT_NEW_SRC_LINE,
108                 disbursementDocument, disbursementDocument.getSourceAccountingLines()));
109         if(disbursementDocument.getSourceAccountingLines().size() > 0) {
110             KualiDecimal totalAmount = KualiDecimal.ZERO;
111             for (SourceAccountingLine accLine : disbursementDocument.getSourceAccountingLines()) {
112                 totalAmount = totalAmount.add(accLine.getAmount());
113             }
114             if (!(totalAmount.equals(disbursementDocument.getDisbVchrCheckTotalAmount()))) {
115                 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_CHECK_TOTAL_AMOUNT, OLEKeyConstants.ERROR_ACC_LINE_TOTAL );
116                 isValid = false;
117             }
118         }
119         if (rulePassed) {
120             if (!disbursementDocument.getDisbVchrCheckTotalAmount().isPositive()) {
121                 GlobalVariables.getMessageMap().putError(OLEPropertyConstants.DISB_VCHR_CHECK_TOTAL_AMOUNT, OLEKeyConstants.ERROR_NEGATIVE_OR_ZERO_CHECK_TOTAL);
122                 isValid = false;
123             }
124             if (isValid) {
125                 updateAccountAmountsWithTotal(disbursementDocument.getSourceAccountingLines(),
126                         disbursementDocument.getDisbVchrCheckTotalAmount());
127                 forward = super.route(mapping, disbursementVoucherForm, request, response);
128             }
129         }
130 
131 
132         return forward;
133     }
134 
135     private void updateAccountAmountsWithTotal(List<OleDisbursementVoucherAccountingLine> sourceAccountingLines, KualiDecimal totalAmount) {
136         if ((totalAmount != null) && KualiDecimal.ZERO.compareTo(totalAmount) != 0) {
137 
138             KualiDecimal accountTotal = KualiDecimal.ZERO;
139             OleDisbursementVoucherAccountingLine lastAccount = null;
140 
141             for (OleDisbursementVoucherAccountingLine account : sourceAccountingLines) {
142                 if (ObjectUtils.isNotNull(account.getAccountLinePercent())) {
143                     BigDecimal pct = new BigDecimal(account.getAccountLinePercent().toString()).divide(new BigDecimal(100));
144                     account.setAmount(new KualiDecimal(pct.multiply(new BigDecimal(totalAmount.toString())).setScale(KualiDecimal.SCALE, KualiDecimal.ROUND_BEHAVIOR)));
145                 } else if (ObjectUtils.isNotNull(account.getAmount()) && ObjectUtils.isNull(account.getAccountLinePercent())) {
146                     KualiDecimal dollar = account.getAmount().multiply(new KualiDecimal(100));
147                     BigDecimal dollarToPercent = dollar.bigDecimalValue().divide((totalAmount.bigDecimalValue()), 0, RoundingMode.FLOOR);
148                     account.setAccountLinePercent(dollarToPercent);
149                 }
150                 accountTotal = accountTotal.add(account.getAmount());
151                 lastAccount = account;
152             }
153         }
154     }
155 
156     @Override
157     public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
158         KualiAccountingDocumentFormBase tmpForm = (KualiAccountingDocumentFormBase) form;
159         saveVendor(mapping, form, request, response);
160         ActionForward forward = super.save(mapping, form, request, response);
161         // need to check on sales tax for all the accounting lines
162         checkSalesTaxRequiredAllLines(tmpForm, tmpForm.getFinancialDocument().getSourceAccountingLines());
163         checkSalesTaxRequiredAllLines(tmpForm, tmpForm.getFinancialDocument().getTargetAccountingLines());
164         return forward;
165     }
166 
167     public ActionForward saveVendor(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
168         OleDisbursementVoucherForm disbursementVoucherForm = (OleDisbursementVoucherForm) form;
169         OleDisbursementVoucherDocument document = disbursementVoucherForm.getDisbursementVoucherDocument();
170         if (document.getDvPayeeDetail().getVendorAliasName() != null && document.getDvPayeeDetail().getVendorAliasName().length() > 0) { /* Checks Vendor name is not equal to null  */
171             /* Getting matching vendor for the given vendor alias name */
172             Map vendorAliasMap = new HashMap();
173             vendorAliasMap.put(OLEConstants.VENDOR_ALIAS_NAME, document.getDvPayeeDetail().getVendorAliasName());
174             org.kuali.rice.krad.service.BusinessObjectService businessObject = SpringContext.getBean(org.kuali.rice.krad.service.BusinessObjectService.class);
175             List<VendorAlias> vendorAliasList = (List<VendorAlias>) getLookupService().findCollectionBySearchHelper(VendorAlias.class, vendorAliasMap, true);
176             if (vendorAliasList != null && vendorAliasList.size() > 0 && vendorAliasList.get(0) != null) {  /* if there matching vendor found for the given vendor alias name */
177                 if (document.getDvPayeeDetail().getDisbVchrVendorHeaderIdNumber() == null && document.getDvPayeeDetail().getDisbVchrVendorDetailAssignedIdNumber() == null) {
178                     GlobalVariables.getMessageMap().putError(PurapConstants.VENDOR_ERRORS, OLEConstants.VENDOR_SELECT);
179                 } else if (document.getDvPayeeDetail().getDisbVchrVendorHeaderIdNumber() != null && document.getDvPayeeDetail().getDisbVchrVendorDetailAssignedIdNumber() != null) {
180                     if (!document.getDvPayeeDetail().getDisbVchrVendorHeaderIdNumber().equals(vendorAliasList.get(0).getVendorHeaderGeneratedIdentifier().toString()) ||
181                             !document.getDvPayeeDetail().getDisbVchrVendorDetailAssignedIdNumber().equals(vendorAliasList.get(0).getVendorDetailAssignedIdentifier().toString())) {
182                         GlobalVariables.getMessageMap().putError(PurapConstants.VENDOR_ERRORS, OLEConstants.VENDOR_NOT_SAME);
183                     }
184                 }
185             } else {     /* If there is no matching vendor found*/
186 
187                 GlobalVariables.getMessageMap().putError(PurapConstants.VENDOR_ERRORS, OLEConstants.VENDOR_NOT_FOUND);
188             }
189         }
190         return mapping.findForward(OLEConstants.MAPPING_BASIC);
191     }
192 
193     public ActionForward selectVendor(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
194         OleDisbursementVoucherForm disbursementVoucherForm = (OleDisbursementVoucherForm) form;
195         OleDisbursementVoucherDocument document = disbursementVoucherForm.getDisbursementVoucherDocument();
196         if (document.getDvPayeeDetail().getVendorAliasName() != null && document.getDvPayeeDetail().getVendorAliasName().length() > 0) { /* Checks Vendor name is not equal to null  */
197             /* Getting matching vendor for the given vendor alias name */
198             Map vendorAliasMap = new HashMap();
199             vendorAliasMap.put(OLEConstants.VENDOR_ALIAS_NAME, document.getDvPayeeDetail().getVendorAliasName());
200             org.kuali.rice.krad.service.BusinessObjectService businessObject = SpringContext.getBean(org.kuali.rice.krad.service.BusinessObjectService.class);
201             List<VendorAlias> vendorAliasList = (List<VendorAlias>) getLookupService().findCollectionBySearchHelper(VendorAlias.class, vendorAliasMap, true);
202             if (vendorAliasList != null && vendorAliasList.size() > 0 && vendorAliasList.get(0) != null) {  /* if there matching vendor found for the given vendor alias name */
203                 String vendorDetailAssignedIdentifier = vendorAliasList.get(0).getVendorDetailAssignedIdentifier().toString();
204                 String vendorHeaderGeneratedIdentifier = vendorAliasList.get(0).getVendorHeaderGeneratedIdentifier().toString();
205                 document.getDvPayeeDetail().setDisbVchrPayeeIdNumber(vendorHeaderGeneratedIdentifier + "-" + vendorDetailAssignedIdentifier);
206                 document.getDvPayeeDetail().setDisbVchrPaymentReasonCode(DisbursementVoucherConstants.DV_PAYEE_TYPE_EMPLOYEE);
207                 refreshAfterAliasNameSelection(mapping, disbursementVoucherForm, request);
208                 refresh(mapping, form, request, response);
209             } else {     /* If there is no matching vendor found*/
210 
211                 GlobalVariables.getMessageMap().putError(PurapConstants.VENDOR_ERRORS, OLEConstants.VENDOR_NOT_FOUND);
212             }
213         }
214         return mapping.findForward(OLEConstants.MAPPING_BASIC);
215     }
216 
217 
218     protected ActionForward refreshAfterAliasNameSelection(ActionMapping mapping, DisbursementVoucherForm dvForm, HttpServletRequest request) {
219         String refreshCaller = "";
220         refreshCaller = OLEConstants.REFRESH_DV_VENDOR_CALLER;
221 
222         DisbursementVoucherDocument document = (DisbursementVoucherDocument) dvForm.getDocument();
223 
224         boolean isPayeeLookupable = OLEConstants.KUALI_DISBURSEMENT_PAYEE_LOOKUPABLE_IMPL.equals(refreshCaller);
225         boolean isAddressLookupable = OLEConstants.KUALI_VENDOR_ADDRESS_LOOKUPABLE_IMPL.equals(refreshCaller);
226 
227         // if a cancel occurred on address lookup we need to reset the payee id and type, rest of fields will still have correct information
228         if (refreshCaller == null && hasFullEdit(document)) {
229             dvForm.setPayeeIdNumber(dvForm.getTempPayeeIdNumber());
230             dvForm.setHasMultipleAddresses(false);
231             document.getDvPayeeDetail().setDisbVchrPayeeIdNumber(dvForm.getTempPayeeIdNumber());
232             document.getDvPayeeDetail().setDisbursementVoucherPayeeTypeCode(dvForm.getOldPayeeType());
233 
234             return null;
235         }
236 
237         // do not execute the further refreshing logic if the refresh caller is not a lookupable
238         if (!isPayeeLookupable && !isAddressLookupable) {
239             return null;
240         }
241 
242         // do not execute the further refreshing logic if a payee is not selected
243         String payeeIdNumber = document.getDvPayeeDetail().getDisbVchrPayeeIdNumber();
244         if (payeeIdNumber == null) {
245             return null;
246         }
247 
248         dvForm.setPayeeIdNumber(payeeIdNumber);
249         dvForm.setHasMultipleAddresses(false);
250 
251         // determine whether the selected vendor has multiple addresses. If so, redirect to the address selection screen
252         if (isPayeeLookupable) {
253             VendorDetail refreshVendorDetail = new VendorDetail();
254             refreshVendorDetail.setVendorNumber(payeeIdNumber);
255             refreshVendorDetail = (VendorDetail) SpringContext.getBean(BusinessObjectService.class).retrieve(refreshVendorDetail);
256 
257             VendorAddress defaultVendorAddress = null;
258             if (refreshVendorDetail != null) {
259                 List<VendorAddress> vendorAddresses = refreshVendorDetail.getVendorAddresses();
260                 boolean hasMultipleAddresses = vendorAddresses != null && vendorAddresses.size() > 1;
261                 dvForm.setHasMultipleAddresses(hasMultipleAddresses);
262 
263                 if (vendorAddresses != null) {
264                     defaultVendorAddress = vendorAddresses.get(0);
265                     setupPayeeAsVendor(dvForm, payeeIdNumber, defaultVendorAddress.getVendorAddressGeneratedIdentifier().toString());
266                 }
267             }
268             return null;
269         }
270 
271         if (isPayeeLookupable && dvForm.isEmployee()) {
272             this.setupPayeeAsEmployee(dvForm, payeeIdNumber);
273         }
274 
275         String payeeAddressIdentifier = request.getParameter(OLEPropertyConstants.VENDOR_ADDRESS_GENERATED_ID);
276         if (isAddressLookupable && StringUtils.isNotBlank(payeeAddressIdentifier)) {
277             setupPayeeAsVendor(dvForm, payeeIdNumber, payeeAddressIdentifier);
278         }
279 
280         String paymentReasonCode = document.getDvPayeeDetail().getDisbVchrPaymentReasonCode();
281         //Commented for the jira issue OLE-3415
282         //addPaymentCodeWarningMessage(dvForm, paymentReasonCode);
283 
284         return null;
285     }
286 
287     private LookupService getLookupService() {
288         return KRADServiceLocatorWeb.getLookupService();
289     }
290 
291 
292 }