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