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 }