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.service; 017 018 import java.io.ByteArrayOutputStream; 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.List; 022 023 import org.kuali.kfs.integration.purap.CapitalAssetSystem; 024 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem; 025 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderQuoteStatus; 026 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderVendorQuote; 027 import org.kuali.kfs.module.purap.businessobject.PurchasingCapitalAssetItem; 028 import org.kuali.kfs.module.purap.document.ContractManagerAssignmentDocument; 029 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument; 030 import org.kuali.kfs.module.purap.document.PurchaseOrderSplitDocument; 031 import org.kuali.kfs.module.purap.document.RequisitionDocument; 032 import org.kuali.kfs.vnd.businessobject.VendorDetail; 033 import org.kuali.rice.kns.bo.Note; 034 import org.kuali.rice.kns.util.KualiDecimal; 035 036 /** 037 * Defines methods that must be implemented by classes providing a PurchaseOrderService. 038 */ 039 public interface PurchaseOrderService extends PurchasingDocumentSpecificService { 040 041 public boolean isPurchaseOrderOpenForProcessing(Integer poId); 042 043 public boolean isPurchaseOrderOpenForProcessing(PurchaseOrderDocument purchaseOrderDocument); 044 045 /** 046 * Creates an automatic purchase order document using the given requisition document 047 * 048 * @param reqDocument The requisition document that this method will use to create the Automated Purchase Order (APO). 049 */ 050 public void createAutomaticPurchaseOrderDocument(RequisitionDocument reqDocument); 051 052 /** 053 * Creates a PurchaseOrderDocument from given RequisitionDocument. Both documents need to be saved after this method is called. 054 * 055 * @param reqDocument The requisition document that this method will use to create the purchase order. 056 * @param newSessionUserId The session user id that we'll use to invoke the performLogicWithFakedUserSession method of 057 * PurapService. 058 * @param contractManagerCode The contract manager code that we'll need to set on the purchase order. 059 * @return The purchase order document object that is created by this method. 060 */ 061 public PurchaseOrderDocument createPurchaseOrderDocument(RequisitionDocument reqDocument, String newSessionUserId, Integer contractManagerCode); 062 063 /** 064 * Creates and saves the purchase order change document (for example, PurchaseOrderAmendmentDocument) based on an existing 065 * purchase order document. 066 * 067 * @param documentNumber The document number of the existing purchase order document from which we try to create a new change 068 * document. 069 * @param docType The document type of the new change document. 070 * @param newDocumentStatusCode The status code that we want to set on the existing purchase order document after the new change 071 * document is created. 072 * @return The resulting new purchase order change document created by this method. 073 */ 074 public PurchaseOrderDocument createAndSavePotentialChangeDocument(String documentNumber, String docType, String newDocumentStatusCode); 075 076 /** 077 * Creates and routes the purchase order change document (for example, PurchaseOrderCloseDocument) based on an existing purchase 078 * order document. 079 * 080 * @param 081 * @param documentNumber The document number of the existing purchase order document from which we try to create a new change 082 * document. 083 * @param docType The document type of the new change document. 084 * @param annotation The annotation that we'll use to invoke the routeDocument method of DocumentService. 085 * @param adhocRoutingRecipients The adhocRoutingRecipients that we'll use to invoke the routeDocument method of 086 * DocumentService. 087 * @param newDocumentStatusCode The status code that we want to set on the existing purchase order document after the new change 088 * document is created. 089 * @return The resulting new purchase order change document created by this method. 090 */ 091 public PurchaseOrderDocument createAndRoutePotentialChangeDocument(String documentNumber, String docType, String annotation, List adhocRoutingRecipients, String newDocumentStatusCode); 092 093 /** 094 * Creates and saves a Purchase Order Split document based on the old PO document, and the items from that PO that the 095 * new Split PO is to contain. 096 * 097 * @param newPOItems The List<PurchaseOrderItem> of the items that the new Split PO is to contain 098 * @param currentDocument The original PurchaseOrderDocument 099 * @param copyNotes A boolean. True if notes are to be copied from the old document to the new. 100 * @param splitNoteText A String containing the text of the note to be added to the old document. 101 * @return A PurchaseOrderSplitDocument containing the given list of items 102 */ 103 public PurchaseOrderSplitDocument createAndSavePurchaseOrderSplitDocument(List<PurchaseOrderItem> newPOItems, PurchaseOrderDocument currentDocument, boolean copyNotes, String splitNoteText); 104 105 /** 106 * Obtains the internal purchasing dollar limit amount for a purchase order document. 107 * 108 * @param po The purchase order document for which this method is obtaining the internal purchasing dollar limit. 109 * @return The internal purchasing dollar limit for the given purchase order document. 110 */ 111 public KualiDecimal getInternalPurchasingDollarLimit(PurchaseOrderDocument po); 112 113 public boolean printPurchaseOrderQuoteRequestsListPDF(String documentNumber, ByteArrayOutputStream baosPDF); 114 115 public boolean printPurchaseOrderQuotePDF(PurchaseOrderDocument po, PurchaseOrderVendorQuote povq, ByteArrayOutputStream baosPDF); 116 117 /** 118 * Creates and displays the pdf document for the purchase order, sets the transmit dates, calls the 119 * takeAllActionsForGivenCriteria method in PurApWorkflowIntegrationService to perform all the workflow related steps that are 120 * necessary as part of the document initial print transmission and then performs the setup of initial of open document of the 121 * purchase order. 122 * 123 * @param documentNumber The document number of the purchase order document that we want to perform the first transmit. 124 * @param baosPDF The ByteArrayOutputStream object that was passed in from the struts action so that we could display the pdf on 125 * the browser. 126 */ 127 public void performPurchaseOrderFirstTransmitViaPrinting(String documentNumber, ByteArrayOutputStream baosPDF); 128 129 /** 130 * Creates and displays the pdf document for the purchase order with a draft watermark 131 * 132 * @param documentNumber The document number of the purchase order document that we want to perform the first transmit. 133 * @param baosPDF The ByteArrayOutputStream object that was passed in from the struts action so that we could display the pdf on 134 * the browser. 135 */ 136 public void performPurchaseOrderPreviewPrinting(String documentNumber, ByteArrayOutputStream baosPDF); 137 138 /** 139 * Generates and displays the purchase order pdf by invoking the generatePurchaseOrderPdf method of the PrintService. 140 * 141 * @param documentNumber The document number of the purchase order document that we want to print the pdf. 142 * @param baosPDF The ByteArrayOutputStream object that we'll use to display the pdf on the browser. 143 */ 144 public void performPrintPurchaseOrderPDFOnly(String documentNumber, ByteArrayOutputStream baosPDF); 145 146 /** 147 * Generates and displays the purchase order retransmit pdf by invoking the generatePurchaseOrderPdfForRetransmission method of 148 * the PrintService. 149 * 150 * @param po The purchase order document to be retransmitted. 151 * @param baosPDF The ByteArrayOutputStream object that we'll use to display the pdf on the browser. 152 */ 153 public void retransmitPurchaseOrderPDF(PurchaseOrderDocument po, ByteArrayOutputStream baosPDF); 154 155 /** 156 * Performs the steps needed to complete the newly approved purchase order document, which consists of setting the current and 157 * pending indicators for the purchase order document and if the status is not pending transmission, then calls the 158 * attemptsSetupOfInitialOpenOfDocument to set the statuses, the initial open date and save the document. 159 * 160 * @param po The newly approved purchase order document that we want to complete. 161 */ 162 public void completePurchaseOrder(PurchaseOrderDocument po); 163 164 public void retransmitB2BPurchaseOrder(PurchaseOrderDocument po); 165 166 public void completePurchaseOrderAmendment(PurchaseOrderDocument po); 167 168 /** 169 * Obtains the purchase order document whose current indicator is true, given a purchase order id which is the 170 * purapDocumentIdentifier. 171 * 172 * @param id The po id (purapDocumentIdentifier) that we'll use to retrieve the current purchase order document. 173 * @return The current purchase order document (the po whose current indicator is true). 174 */ 175 public PurchaseOrderDocument getCurrentPurchaseOrder(Integer id); 176 177 /** 178 * Obtains the purchase order document given the document number. 179 * 180 * @param documentNumber The document number of the purchase order that we want to retrieve. 181 * @return The purchase order document whose document number is the given document number. 182 */ 183 public PurchaseOrderDocument getPurchaseOrderByDocumentNumber(String documentNumber); 184 185 /** 186 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as its status, then save 187 * the purchase order. 188 * 189 * @param newPO The new purchase order document that has been approved. 190 */ 191 public void setCurrentAndPendingIndicatorsForApprovedPODocuments(PurchaseOrderDocument newPO); 192 193 /** 194 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 195 * save the purchase order. 196 * 197 * @param newPO The new purchase order document that has been disapproved. 198 */ 199 public void setCurrentAndPendingIndicatorsForDisapprovedChangePODocuments(PurchaseOrderDocument newPO); 200 201 /** 202 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 203 * save the purchase order. 204 * 205 * @param newPO The new purchase order document that has been canceled. 206 */ 207 public void setCurrentAndPendingIndicatorsForCancelledChangePODocuments(PurchaseOrderDocument newPO); 208 209 /** 210 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 211 * save the purchase order. 212 * 213 * @param newPO The new purchase order reopen document that has been canceled. 214 */ 215 public void setCurrentAndPendingIndicatorsForCancelledReopenPODocuments(PurchaseOrderDocument newPO); 216 217 /** 218 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 219 * save the purchase order. 220 * 221 * @param newPO The new purchase order reopen document that has been disapproved. 222 */ 223 public void setCurrentAndPendingIndicatorsForDisapprovedReopenPODocuments(PurchaseOrderDocument newPO); 224 225 /** 226 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 227 * save the purchase order 228 * 229 * @param newPO The new purchase order remove hold document that has been canceled. 230 */ 231 public void setCurrentAndPendingIndicatorsForCancelledRemoveHoldPODocuments(PurchaseOrderDocument newPO); 232 233 /** 234 * Sets the current and pending indicators of the new purchase order and the old purchase order as well as their statuses, then 235 * save the purchase order. 236 * 237 * @param newPO The new purchase order remove hold document that has been disapproved. 238 */ 239 public void setCurrentAndPendingIndicatorsForDisapprovedRemoveHoldPODocuments(PurchaseOrderDocument newPO); 240 241 /** 242 * Obtains the oldest purchase order given the purchase order object to be used to search, then calls the updateNotes method to 243 * set the notes on the oldest purchase order and finally return the oldest purchase order. 244 * 245 * @param po The current purchase order object from which we want to obtain the oldest purchase order. 246 * @param documentBusinessObject The documentBusinessObject of the current purchase order object. 247 * @return The oldest purchase order whose purchase order id is the same as the current purchase order's id. 248 */ 249 public PurchaseOrderDocument getOldestPurchaseOrder(PurchaseOrderDocument po, PurchaseOrderDocument documentBusinessObject); 250 251 /** 252 * Obtains all the notes that belong to this purchase order given the purchase order id. 253 * 254 * @param id The purchase order id (purapDocumentIdentifier). 255 * @return The list of notes that belong to this purchase order. 256 */ 257 public ArrayList<Note> getPurchaseOrderNotes(Integer id); 258 259 public ArrayList<PurchaseOrderQuoteStatus> getPurchaseOrderQuoteStatusCodes(); 260 261 /** 262 * Performs a threshold check on the purchase order to determine if any attribute on the purchase order 263 * falls within a defined threshold. This check is only perfromed if the receiving required flag is set to N. 264 * 265 * @param po 266 */ 267 public void setReceivingRequiredIndicatorForPurchaseOrder(PurchaseOrderDocument po); 268 269 /** 270 * If there are commodity codes on the items on the PurchaseOrderDocument that 271 * haven't existed yet on the vendor that the PurchaseOrderDocument is using, 272 * then we will spawn a new VendorDetailMaintenanceDocument automatically to 273 * update the vendor with the commodity codes that aren't already existing on 274 * the vendor. 275 * 276 * @param po The PurchaseOrderDocument containing the vendor that we want to update. 277 */ 278 public void updateVendorCommodityCode(PurchaseOrderDocument po); 279 280 /** 281 * Checks the item list for newly added unordered items. 282 * 283 * @param po 284 * @return 285 */ 286 public boolean hasNewUnorderedItem(PurchaseOrderDocument po); 287 288 /** 289 * Check whether each of the items contain commodity code, if so then loop 290 * through the vendor commodity codes on the vendor to find out whether the 291 * commodity code on the item has existed on the vendor. While doing that, 292 * also check whether there exists a default commodity code on the vendor, 293 * although we only need to check this until we find a vendor commodity code 294 * with default indicator set to true. If we didn't find any matching 295 * commodity code in the existing vendor commodity codes, then add the new 296 * commodity code to a List of commodity code, create a new vendor commodity 297 * code and set all of its attributes appropriately, including setting the 298 * default indicator to true if we had not found any existing default commodity 299 * code on the vendor, then add the newly created vendor commodity code to 300 * the vendor (which is a deep copy of the original vendor on the PO). 301 * After we're done with all of the items, if the List that contains the 302 * commodity code that were being added to the vendor is not empty, then 303 * for each entry on that list, we should create an empty VendorCommodityCode 304 * to be added to the old vendor (the original vendor that is on the PO document). 305 * The reason we're combining all of these processing here is so that we don't 306 * need to loop through items and vendor commodity codes too many times. 307 * 308 * @param po The PurchaseOrderDocument containing the vendor that we want to update. 309 * 310 * @return VendorDetail the vendorDetail object which is a deep copy of the original 311 * vendorDetail on the PurchaseOrderDocument, whose commodity codes have 312 * already been updated based on our findings on the items' commodity codes. 313 */ 314 public VendorDetail updateVendorWithMissingCommodityCodesIfNecessary(PurchaseOrderDocument po); 315 316 /** 317 * Determines if a purchase order item is new unordered item. 318 * 319 * @param poItem 320 * @return 321 */ 322 public boolean isNewUnorderedItem(PurchaseOrderItem poItem); 323 324 /** 325 * Determines if a purchase order item is newly added on 326 * the Purchase Order Amendment Document. 327 * 328 * @param poItem 329 * @return 330 */ 331 public boolean isNewItemForAmendment(PurchaseOrderItem poItem); 332 333 /** 334 * Used to provide sublists of the list of the original PO's items according to whether they 335 * are marked to be moved or not. Retrieving the item from the hash with the key of 'movingPOItems' 336 * will retrieve those Items which should move, using 'remainingPOItems'. 337 * 338 * @param items A List<PurchaseOrderItem> from the original PO of a Split. 339 * @return A HashMap<String, List<PurchaseOrderItem>> of categorized lists of items 340 */ 341 public HashMap<String, List<PurchaseOrderItem>> categorizeItemsForSplit(List<PurchaseOrderItem> items); 342 343 /** 344 * Creates a PurchaseOrderVendorQuote based on the data on the selected vendor and the document number. 345 * 346 * @param headerId The vendorHeaderGeneratedIdentifier of the selected vendor. 347 * @param detailId The vendorDetailAssignedIdentifier of the selected vendor. 348 * @param documentNumber The documentNumber of the PurchaseOrderDocument containing this quote. 349 * @return The resulting PurchaseOrderVendorQuote object. 350 */ 351 public PurchaseOrderVendorQuote populateQuoteWithVendor(Integer headerId, Integer detailId, String documentNumber); 352 353 /** 354 * 355 * This method takes care of creating PurchaseOrderDocuments from a list of Requisitions on an ACM 356 * @param acmDoc An assign a contract manager document 357 */ 358 public void processACMReq(ContractManagerAssignmentDocument acmDoc); 359 360 /** 361 * This gets a list of Purchase Orders in Open status and checks to see if their 362 * line item encumbrances are all fully disencumbered and if so then the Purchase 363 * Order is closed and notes added to indicate the change occurred in batch 364 * 365 * @return boolean true if the job is completed successfully and false otherwise. 366 */ 367 public boolean autoCloseFullyDisencumberedOrders(); 368 369 370 /** 371 * - PO status is OPEN 372 * - Recurring payment type code is not null 373 * - Vendor Choice is not Sub-Contract 374 * - PO End Date <= parm date (comes from system parameter) 375 * - Verify that the system parameter date entered is not greater than the current date minus three months. 376 * If the date entered is invalid, the batch process will halt and an error will be generated. 377 * - Close and disencumber all recurring PO's that have end dates less than 378 * the system parameter date. 379 * - Set the system parameter date to mm/dd/yyyy after processing. 380 * - Send email indicating that the job ran and which orders were closed. 381 * Mail it to the AUTO_CLOSE_RECURRING_PO_EMAIL_ADDRESSES in system parameter. 382 * 383 * @return boolean true if the job is completed successfully and false otherwise. 384 */ 385 public boolean autoCloseRecurringOrders(); 386 387 388 /** 389 * Return a list of PurchasingCapitalAssetItems where each item would have a CapitalAssetSystem. The CapitalAssetSystem provides 390 * the capital asset information such as asset numbers and asset type. 391 * 392 * @param poId Purchase Order ID used to retrieve the asset information for the current PO 393 * @return List of PurchasingCapitalAssetItems (each of which contain a CapitalAssetSystem) 394 */ 395 public List<PurchasingCapitalAssetItem> retrieveCapitalAssetItemsForIndividual(Integer poId); 396 397 398 /** 399 * Return a CapitalAssetSystem which provides the capital asset information such as asset numbers and asset type. 400 * 401 * @param poId Purchase Order ID used to retrieve the asset information for the current PO 402 * @return CapitalAssetSystem 403 */ 404 public CapitalAssetSystem retrieveCapitalAssetSystemForOneSystem(Integer poId); 405 406 407 /** 408 * Return a list of CapitalAssetSystems which provide the capital asset information such as asset numbers and asset type. 409 * 410 * @param poId Purchase Order ID used to retrieve the asset information for the current PO 411 * @return List of CapitalAssetSystems 412 */ 413 public List<CapitalAssetSystem> retrieveCapitalAssetSystemsForMultipleSystem(Integer poId); 414 415 416 /** 417 * This method gets all the Purchase orders that are waiting for faxing 418 * @return List of POs 419 */ 420 public List<PurchaseOrderDocument> getPendingPurchaseOrderFaxes(); 421 422 /** 423 * Determines whether to display the amend button for the purchase order document. 424 * The document status must be open, the purchase order must be current and not pending and the 425 * user must be in purchasing group. These are the conditions for displaying the payment hold 426 * button. In addition to these conditions, we also have to check that there is no In Process 427 * Payment Requests nor Credit Memos associated with the PO. 428 * 429 * @return boolean true if the amendment possible for the purchase order. 430 */ 431 public boolean canAmendPurchaseOrder(PurchaseOrderDocument purchaseOrder); 432 433 /** 434 * Determines whether to display the amend and payment hold buttons for the purchase order document. 435 * The document status must be open, the purchase order must be current and not pending and the 436 * user must be in purchasing group. 437 * 438 * @return boolean true if the payment hold is possible for the purchase order document. 439 */ 440 public boolean canHoldPayment(PurchaseOrderDocument purchaseOrder); 441 442 443 }