View Javadoc
1   /*
2    * Copyright 2008-2009 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.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/ecl2.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.module.purap.document;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.ole.module.purap.PurapConstants;
20  import org.kuali.ole.module.purap.PurapWorkflowConstants;
21  import org.kuali.ole.module.purap.businessobject.LineItemReceivingItem;
22  import org.kuali.ole.module.purap.businessobject.PurchaseOrderItem;
23  import org.kuali.ole.module.purap.document.service.OlePurapService;
24  import org.kuali.ole.module.purap.document.service.PurapService;
25  import org.kuali.ole.module.purap.document.service.PurchaseOrderService;
26  import org.kuali.ole.module.purap.document.service.ReceivingService;
27  import org.kuali.ole.module.purap.document.validation.event.AttributedContinuePurapEvent;
28  import org.kuali.ole.sys.OLEConstants;
29  import org.kuali.ole.sys.context.SpringContext;
30  import org.kuali.rice.core.api.util.type.KualiDecimal;
31  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange;
32  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
33  import org.kuali.rice.kns.service.DataDictionaryService;
34  import org.kuali.rice.krad.bo.DocumentHeader;
35  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
36  import org.kuali.rice.krad.util.KRADPropertyConstants;
37  
38  import java.util.*;
39  
40  /**
41   * @author Kuali Nervous System Team (kualidev@oncourse.iu.edu)
42   */
43  public class LineItemReceivingDocument extends ReceivingDocumentBase {
44  
45      //Collections
46      protected List<LineItemReceivingItem> items;
47  
48      /**
49       * Default constructor.
50       */
51      public LineItemReceivingDocument() {
52          super();
53          items = new ArrayList();
54      }
55  
56      private static transient OlePurapService olePurapService;
57  
58      public static OlePurapService getOlePurapService() {
59          if (olePurapService == null) {
60              olePurapService = SpringContext.getBean(OlePurapService.class);
61          }
62          return olePurapService;
63      }
64  
65  
66      public void initiateDocument() {
67          super.initiateDocument();
68          this.setAppDocStatus(PurapConstants.LineItemReceivingStatuses.APPDOC_IN_PROCESS);
69      }
70  
71      public void populateReceivingLineFromPurchaseOrder(PurchaseOrderDocument po) {
72  
73          //populate receiving line document from purchase order
74          this.setPurchaseOrderIdentifier(po.getPurapDocumentIdentifier());
75          this.getDocumentHeader().setOrganizationDocumentNumber(po.getDocumentHeader().getOrganizationDocumentNumber());
76          this.setAccountsPayablePurchasingDocumentLinkIdentifier(po.getAccountsPayablePurchasingDocumentLinkIdentifier());
77  
78          //copy vendor
79          this.setVendorHeaderGeneratedIdentifier(po.getVendorHeaderGeneratedIdentifier());
80          this.setVendorDetailAssignedIdentifier(po.getVendorDetailAssignedIdentifier());
81          this.setVendorName(po.getVendorName());
82          this.setVendorNumber(po.getVendorNumber());
83          this.setVendorAddressGeneratedIdentifier(po.getVendorAddressGeneratedIdentifier());
84          this.setVendorLine1Address(po.getVendorLine1Address());
85          this.setVendorLine2Address(po.getVendorLine2Address());
86          this.setVendorCityName(po.getVendorCityName());
87          this.setVendorStateCode(po.getVendorStateCode());
88          this.setVendorPostalCode(po.getVendorPostalCode());
89          this.setVendorCountryCode(po.getVendorCountryCode());
90  
91          //copy alternate vendor
92          this.setAlternateVendorName(po.getAlternateVendorName());
93          this.setAlternateVendorNumber(po.getAlternateVendorNumber());
94          this.setAlternateVendorDetailAssignedIdentifier(po.getAlternateVendorDetailAssignedIdentifier());
95          this.setAlternateVendorHeaderGeneratedIdentifier(po.getAlternateVendorHeaderGeneratedIdentifier());
96  
97          //copy delivery
98          this.setDeliveryBuildingCode(po.getDeliveryBuildingCode());
99          this.setDeliveryBuildingLine1Address(po.getDeliveryBuildingLine1Address());
100         this.setDeliveryBuildingLine2Address(po.getDeliveryBuildingLine2Address());
101         this.setDeliveryBuildingName(po.getDeliveryBuildingName());
102         this.setDeliveryBuildingRoomNumber(po.getDeliveryBuildingRoomNumber());
103         this.setDeliveryCampusCode(po.getDeliveryCampusCode());
104         this.setDeliveryCityName(po.getDeliveryCityName());
105         this.setDeliveryCountryCode(po.getDeliveryCountryCode());
106         this.setDeliveryInstructionText(po.getDeliveryInstructionText());
107         this.setDeliveryPostalCode(po.getDeliveryPostalCode());
108         this.setDeliveryRequiredDate(po.getDeliveryRequiredDate());
109         this.setDeliveryRequiredDateReasonCode(po.getDeliveryRequiredDateReasonCode());
110         this.setDeliveryStateCode(po.getDeliveryStateCode());
111         this.setDeliveryToEmailAddress(po.getDeliveryToEmailAddress());
112         this.setDeliveryToName(po.getDeliveryToName());
113         this.setDeliveryToPhoneNumber(po.getDeliveryToPhoneNumber());
114 
115         //copy purchase order items
116         for (PurchaseOrderItem poi : (List<PurchaseOrderItem>) po.getItems()) {
117             //TODO: Refactor this check into a service call. route FYI during submit
118             if (poi.isItemActiveIndicator() &&
119                     poi.getItemType().isQuantityBasedGeneralLedgerIndicator() &&
120                     poi.getItemType().isLineItemIndicator()) {
121                 this.getItems().add(new LineItemReceivingItem(poi, this));
122             }
123         }
124 
125         populateDocumentDescription(po);
126     }
127 
128     /**
129      * Perform logic needed to clear the initial fields on a Receiving Line Document
130      */
131     public void clearInitFields(boolean fromPurchaseOrder) {
132         // Clearing document overview fields
133         this.getDocumentHeader().setDocumentDescription(null);
134         this.getDocumentHeader().setExplanation(null);
135         this.getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(null);
136         this.getDocumentHeader().setOrganizationDocumentNumber(null);
137 
138         // Clearing document Init fields
139         if (fromPurchaseOrder == false) {
140             this.setPurchaseOrderIdentifier(null);
141         }
142         this.setShipmentReceivedDate(null);
143         this.setShipmentPackingSlipNumber(null);
144         this.setShipmentBillOfLadingNumber(null);
145         this.setCarrierCode(null);
146     }
147 
148 
149     @Override
150     public void prepareForSave(KualiDocumentEvent event) {
151 
152         // first populate, then call super
153         if (event instanceof AttributedContinuePurapEvent) {
154             SpringContext.getBean(ReceivingService.class).populateReceivingLineFromPurchaseOrder(this);
155         }
156 
157         super.prepareForSave(event);
158     }
159 
160     @Override
161     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
162         super.doRouteStatusChange(statusChangeEvent);
163         // DOCUMENT CANCELED
164         // If the document is canceled then set the line item receiving 
165         // status code to CANC.
166         if (this.getFinancialSystemDocumentHeader().getWorkflowDocument().isCanceled()) {
167             setAppDocStatus(PurapConstants.LineItemReceivingStatuses.APPDOC_CANCELLED);
168             SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this);
169         }
170     }
171 
172     @Override
173     public void doRouteLevelChange(DocumentRouteLevelChange change) {
174         //If the new node is Outstanding Transactions then we want to set the line item
175         //receiving status code to APOO.
176         if (StringUtils.equals(PurapConstants.LineItemReceivingDocumentStrings.AWAITING_PO_OPEN_STATUS, change.getNewNodeName())) {
177             setAppDocStatus(PurapConstants.LineItemReceivingStatuses.APPDOC_AWAITING_PO_OPEN_STATUS);
178             SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this);
179         }
180         //If the new node is Join, this means we're done with the routing, so we'll set
181         //the line item receiving status code to CMPT.
182         else if (StringUtils.equals(PurapConstants.LineItemReceivingDocumentStrings.JOIN_NODE, change.getNewNodeName())) {
183             setAppDocStatus(PurapConstants.LineItemReceivingStatuses.APPDOC_COMPLETE);
184             SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this);
185         }
186         SpringContext.getBean(PurapService.class).saveDocumentNoValidation(this);
187     }
188 
189     /**
190      * @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper()
191      */
192     protected LinkedHashMap toStringMapper_RICE20_REFACTORME() {
193         LinkedHashMap m = new LinkedHashMap();
194         m.put("documentNumber", this.documentNumber);
195         return m;
196     }
197 
198     public Class getItemClass() {
199         return LineItemReceivingItem.class;
200     }
201 
202     public List getItems() {
203         return items;
204     }
205 
206     public void setItems(List items) {
207         this.items = items;
208     }
209 
210     public LineItemReceivingItem getItem(int pos) {
211         return (LineItemReceivingItem) items.get(pos);
212     }
213 
214     public void addItem(LineItemReceivingItem item) {
215         getItems().add(item);
216     }
217 
218     public void deleteItem(int lineNum) {
219         if (getItems().remove(lineNum) == null) {
220             // throw error here
221         }
222     }
223 
224     protected void populateDocumentDescription(PurchaseOrderDocument poDocument) {
225         String description =  getOlePurapService().getParameter(OLEConstants.LINE_ITEM_RCV_DESC);
226         Map<String,String> descMap = new HashMap<>();
227         descMap.put(OLEConstants.PO_DOC_ID,poDocument.getPurapDocumentIdentifier().toString());
228         descMap.put(OLEConstants.VENDOR_NAME,poDocument.getVendorName());
229         description = getOlePurapService().setDocumentDescription(description,descMap);
230         int noteTextMaxLength = SpringContext.getBean(DataDictionaryService.class).getAttributeMaxLength(DocumentHeader.class, KRADPropertyConstants.DOCUMENT_DESCRIPTION).intValue();
231         if (noteTextMaxLength < description.length()) {
232             description = description.substring(0, noteTextMaxLength);
233         }
234         getDocumentHeader().setDocumentDescription(description);
235     }
236 
237 
238     protected boolean isRelatesToOutstandingTransactionsRequired() {
239         return SpringContext.getBean(ReceivingService.class).hasNewUnorderedItem(this) && !SpringContext.getBean(PurchaseOrderService.class).isPurchaseOrderOpenForProcessing(getPurchaseOrderDocument());
240     }
241 
242     /**
243      * Provides answers to the following splits:
244      * RelatesToOutstandingTransactions
245      *
246      * @see org.kuali.ole.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
247      */
248     public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
249         if (nodeName.equals(PurapWorkflowConstants.RELATES_TO_OUTSTANDING_TRANSACTIONS))
250             return isRelatesToOutstandingTransactionsRequired();
251         throw new UnsupportedOperationException("Cannot answer split question for this node you call \"" + nodeName + "\"");
252     }
253 
254     public List buildListOfDeletionAwareLists() {
255         List managedLists = super.buildListOfDeletionAwareLists();
256         managedLists.add(this.getItems());
257         return managedLists;
258     }
259 
260     public KualiDecimal getTotalItemReceivedGivenLineNumber(Integer lineNumber) {
261         for (LineItemReceivingItem item : items) {
262             if (item.getItemLineNumber().equals(lineNumber)) {
263                 return item.getItemReceivedTotalQuantity();
264             }
265         }
266         return new KualiDecimal(0);
267     }
268 }