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.batch;
017    
018    import java.math.BigDecimal;
019    import java.util.Date;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.kuali.kfs.integration.purap.CapitalAssetLocation;
026    import org.kuali.kfs.module.purap.PurapConstants;
027    import org.kuali.kfs.module.purap.PurapConstants.POCostSources;
028    import org.kuali.kfs.module.purap.PurapConstants.POTransmissionMethods;
029    import org.kuali.kfs.module.purap.PurapConstants.RequisitionSources;
030    import org.kuali.kfs.module.purap.PurapConstants.RequisitionStatuses;
031    import org.kuali.kfs.module.purap.businessobject.ContractManagerAssignmentDetail;
032    import org.kuali.kfs.module.purap.businessobject.PurchaseOrderView;
033    import org.kuali.kfs.module.purap.businessobject.PurchasingCapitalAssetItem;
034    import org.kuali.kfs.module.purap.businessobject.RequisitionAccount;
035    import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetItem;
036    import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetLocation;
037    import org.kuali.kfs.module.purap.businessobject.RequisitionCapitalAssetSystem;
038    import org.kuali.kfs.module.purap.businessobject.RequisitionItem;
039    import org.kuali.kfs.module.purap.document.ContractManagerAssignmentDocument;
040    import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
041    import org.kuali.kfs.module.purap.document.RequisitionDocument;
042    import org.kuali.kfs.module.purap.document.service.PurapService;
043    import org.kuali.kfs.module.purap.document.service.RequisitionService;
044    import org.kuali.kfs.sys.KFSConstants;
045    import org.kuali.kfs.sys.batch.AbstractStep;
046    import org.kuali.kfs.sys.batch.Job;
047    import org.kuali.kfs.sys.batch.TestingStep;
048    import org.kuali.rice.kew.exception.WorkflowException;
049    import org.kuali.rice.kns.UserSession;
050    import org.kuali.rice.kns.bo.DocumentHeader;
051    import org.kuali.rice.kns.bo.Parameter;
052    import org.kuali.rice.kns.document.Document;
053    import org.kuali.rice.kns.exception.ValidationException;
054    import org.kuali.rice.kns.service.BusinessObjectService;
055    import org.kuali.rice.kns.service.DocumentService;
056    import org.kuali.rice.kns.service.PersistenceStructureService;
057    import org.kuali.rice.kns.util.GlobalVariables;
058    import org.kuali.rice.kns.util.KNSConstants;
059    import org.kuali.rice.kns.util.KualiDecimal;
060    import org.kuali.rice.kns.util.ObjectUtils;
061    import org.kuali.rice.kns.util.TypedArrayList;
062    
063    public class PurapMassRequisitionStep extends AbstractStep implements TestingStep {
064        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PurapMassRequisitionStep.class);
065    
066        private DocumentService documentService;
067        private RequisitionService requisitionService;
068        private PurapService purapService;
069        private BusinessObjectService boService;
070        private PersistenceStructureService psService;
071    
072        private final int NUM_DOCS_TO_CREATE = 25; // number of each document type to create
073        private final int ROUTE_TO_FINAL_SECONDS_LIMIT = 240; // number of seconds to wait for routing of documents to Final.
074        private final String RUN_INDICATOR_PARAMETER_NAMESPACE_STEP = "PurapMassRequisitionStep";
075        private final String RUN_INDICATOR_PARAMETER_VALUE = "N";
076        private final String RUN_INDICATOR_PARAMETER_ALLOWED = "A";
077        private final String RUN_INDICATOR_PARAMETER_DESCRIPTION = "Tells the job framework whether to run this job or not; because the PurapMassRequisitionJob needs to only be run once after database initialization.";
078        private final String RUN_INDICATOR_PARAMETER_TYPE = "CONFG";
079    
080        public boolean execute(String jobName, Date jobRunDate) throws InterruptedException {
081            LOG.info("Starting execution of PurapMassRequisitionStep");
082    
083            Parameter runIndicatorParameter = (Parameter) boService.findByPrimaryKey(Parameter.class, this.buildRunParameterSearchKeyMap());
084            if (ObjectUtils.isNull(runIndicatorParameter) || "Y".equals(runIndicatorParameter.getParameterValue())) {
085                // save runParameter as "N" so that the job won't run until DB has been cleared
086                setInitiatedRunParameter();
087    
088                for (int i = 0; i < NUM_DOCS_TO_CREATE; i++) {
089    
090                    try {
091                        LOG.info("Setting user session for routing of quantity document.");
092                        GlobalVariables.setUserSession(new UserSession("khuntley"));
093                        // create document
094                        RequisitionDocument reqDoc = populateQuantityDocument();
095    
096                        LOG.info("Blanket approving quantity requisition document.");
097                        // route it
098                        documentService.blanketApproveDocument(reqDoc, "auto-routing: Test Requisition Job.", null);
099                    }
100                    catch (WorkflowException e) {
101                        e.printStackTrace();
102                    }
103                    Thread.sleep(5000);
104                }
105    
106                for (int i = 0; i < NUM_DOCS_TO_CREATE; i++) {
107    
108                    try {
109                        LOG.info("Setting user session for routing of non-quantity document.");
110                        GlobalVariables.setUserSession(new UserSession("khuntley"));
111                        // create document
112                        RequisitionDocument reqDoc = populateNonQuantityDocument();
113                        LOG.info("Blanket approving non-quantity requisition document.");
114                        // route it
115                        documentService.blanketApproveDocument(reqDoc, "auto-routing: Test Requisition Job.", null);
116                    }
117                    catch (WorkflowException e) {
118                        e.printStackTrace();
119                    }
120                    Thread.sleep(5000);
121                }
122    
123    
124                // TODO leaving CAMS docs commented out until problem is fixed
125                // for (int i = 0; i < NUM_DOCS_TO_CREATE; i++) {
126                // RequisitionDocument reqDoc = null;
127                // try {
128                // LOG.info("Setting user session for routing of requisition with capital asset data and addresses.");
129                // GlobalVariables.setUserSession(new UserSession("khuntley"));
130                // // create document
131                // reqDoc = populateCapitalAsset_Individual_WithAddresses_Document();
132                // Thread.sleep(10000);
133                // LOG.info("Blanket approving requisition with capital asset data and addresses.");
134                // // route it
135                // documentService.blanketApproveDocument(reqDoc, "auto-routing: Test Requisition Job.", null);
136                // }
137                // catch (WorkflowException e) {
138                // e.printStackTrace();
139                // }
140                // catch (ValidationException ve) {
141                // continue;
142                // }
143                // Thread.sleep(5000);
144                //
145                // // Use Contract Manager Assignment to create PO.
146                // LOG.info("Setting user session for contract manager assignment of requisition with capital asset data and addresses.");
147                // GlobalVariables.setUserSession(new UserSession("parke"));
148                // LOG.info("Routing Contract Manager Assignment document for requisition with capital asset data and addresses.");
149                // ContractManagerAssignmentDocument acmDoc = createAndRouteContractManagerAssignmentDocument(reqDoc);
150                //
151                // Thread.sleep(20000);
152                //
153                // LOG.info("Routing Purchase Order document for requisition with capital asset data and addresses.");
154                // createAndRoutePurchaseOrderDocument(reqDoc, acmDoc);
155                //
156                // Thread.sleep(5000);
157                // }
158                //
159                // for (int i = 0; i < NUM_DOCS_TO_CREATE; i++) {
160                // RequisitionDocument reqDoc = null;
161                // try {
162                // LOG.info("Setting user session for routing of BAS requisition.");
163                // GlobalVariables.setUserSession(new UserSession("khuntley"));
164                // // create document
165                // reqDoc = populateCapitalAsset_Individual_Unfilled_Document();
166                // Thread.sleep(10000);
167                // LOG.info("Blanket approving BAS requisition.");
168                // // route it
169                // documentService.blanketApproveDocument(reqDoc, "auto-routing: Test Requisition Job.", null);
170                // }
171                // catch (WorkflowException e) {
172                // e.printStackTrace();
173                // }
174                // catch (ValidationException ve) {
175                // continue;
176                // }
177                // Thread.sleep(5000);
178                //
179                // // Use Contract Manager Assignment to create PO.
180                // LOG.info("Setting user session for contract manager assignment BAS requisition.");
181                // GlobalVariables.setUserSession(new UserSession("parke"));
182                // LOG.info("Routing Contract Manager Assignment document for BAS requisition.");
183                // ContractManagerAssignmentDocument acmDoc = createAndRouteContractManagerAssignmentDocument(reqDoc);
184                //
185                // Thread.sleep(20000);
186                //
187                // LOG.info("Routing Purchase Order document for BAS requisition");
188                // createAndRoutePurchaseOrderDocument(reqDoc, acmDoc);
189                //
190                // Thread.sleep(5000);
191                // }
192            }
193    
194            Thread.sleep(60000);
195            return true;
196        }
197    
198        private RequisitionDocument populateQuantityDocument() {
199            LOG.info("Creating a new requisition.");
200            RequisitionDocument reqDoc = null;
201            try {
202                reqDoc = (RequisitionDocument) documentService.getNewDocument(RequisitionDocument.class);
203                LOG.info("Populating a new requisition.");
204                // RequisitionDocument reqDoc = new RequisitionDocument();
205                // set doc attributes
206                reqDoc.getDocumentHeader().setExplanation("batch created quantity document");
207                DocumentHeader documentHeader = reqDoc.getDocumentHeader();
208                documentHeader.setDocumentDescription("batch created quantity document");
209                reqDoc.setDocumentFundingSourceCode("INST");
210                reqDoc.setRequisitionSourceCode(RequisitionSources.STANDARD_ORDER);
211                reqDoc.setPurchaseOrderTransmissionMethodCode(POTransmissionMethods.NOPRINT);
212                reqDoc.setPurchaseOrderCostSourceCode(POCostSources.ESTIMATE);
213                reqDoc.setChartOfAccountsCode("KO");
214                reqDoc.setOrganizationCode("SBSC");
215                reqDoc.setDeliveryCampusCode("KO");
216                reqDoc.setRequestorPersonName("WATSON,TERRENCE G");
217                reqDoc.setRequestorPersonEmailAddress("tw@kuali.org");
218                reqDoc.setRequestorPersonPhoneNumber("812-555-5555");
219                reqDoc.setDeliveryBuildingCode("ADMN");
220                reqDoc.setDeliveryBuildingName("Administration");
221                reqDoc.setDeliveryBuildingRoomNumber("100");
222                reqDoc.setDeliveryBuildingLine1Address("98 smart street");
223                reqDoc.setDeliveryCityName("brainy");
224                reqDoc.setDeliveryStateCode("CA");
225                reqDoc.setDeliveryPostalCode("46202");
226                reqDoc.setDeliveryCountryCode("US");
227                reqDoc.setDeliveryToName("front desk");
228                reqDoc.setBillingName("THE UNIVERSITY");
229                reqDoc.setBillingLine1Address("ACCOUNTS PAYABLE");
230                reqDoc.setBillingCityName("BUTTER NUT");
231                reqDoc.setBillingStateCode("SC");
232                reqDoc.setBillingPostalCode("47402");
233                reqDoc.setBillingCountryCode("US");
234                reqDoc.setBillingPhoneNumber("111-111-1111");
235                reqDoc.setPurchaseOrderAutomaticIndicator(false);
236                reqDoc.setStatusCode(RequisitionStatuses.IN_PROCESS);
237                reqDoc.setVendorHeaderGeneratedIdentifier(1002);
238                reqDoc.setVendorDetailAssignedIdentifier(0);
239                reqDoc.setVendorName("MK CORPORATION ACTIVE");
240                reqDoc.setVendorLine1Address("3894 SOUTH ST");
241                reqDoc.setVendorLine2Address("P.O. BOX 3455");
242                reqDoc.setVendorCityName("SPRINGFIELD");
243                reqDoc.setVendorStateCode("IL");
244                reqDoc.setVendorPostalCode("33555");
245                reqDoc.setVendorCountryCode("US");
246                reqDoc.setUseTaxIndicator(false);
247    
248                // set item attributes
249                RequisitionItem item1 = new RequisitionItem();
250                item1.setItemLineNumber(new Integer(1));
251                item1.setItemUnitOfMeasureCode("PCS");
252                item1.setItemCatalogNumber("P10M980");
253                item1.setItemDescription("Copy Paper - 8 1/2 x 11, White, 92, 20lb");
254                item1.setItemUnitPrice(new BigDecimal(30.20));
255                item1.setItemTypeCode("ITEM");
256                item1.setItemQuantity(new KualiDecimal(20));
257                item1.setExtendedPrice(new KualiDecimal(604));
258                item1.setItemAssignedToTradeInIndicator(false);
259    
260                // set accounting line attributes
261                RequisitionAccount account1 = new RequisitionAccount();
262                account1.setPostingYear(2004);
263                account1.setChartOfAccountsCode("BL");
264                account1.setAccountNumber("1023200");
265                account1.setFinancialObjectCode("4100");
266                account1.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
267                account1.setAmount(new KualiDecimal("100"));
268                account1.setAccountLinePercent(new BigDecimal("100"));
269    
270                item1.getSourceAccountingLines().add(account1);
271                reqDoc.getItems().add(item1);
272                reqDoc.fixItemReferences();
273            }
274            catch (WorkflowException e1) {
275                e1.printStackTrace();
276            }
277            return reqDoc;
278        }
279    
280        private RequisitionDocument populateNonQuantityDocument() {
281            RequisitionDocument reqDoc = null;
282            try {
283                reqDoc = (RequisitionDocument) documentService.getNewDocument(RequisitionDocument.class);
284    
285                // RequisitionDocument reqDoc = new RequisitionDocument();
286                // set doc attributes
287                reqDoc.getDocumentHeader().setExplanation("batch created non-quantity document");
288                DocumentHeader documentHeader = reqDoc.getDocumentHeader();
289                documentHeader.setDocumentDescription("batch created non-quantity document");
290                reqDoc.setDocumentFundingSourceCode("INST");
291                reqDoc.setRequisitionSourceCode(RequisitionSources.STANDARD_ORDER);
292                reqDoc.setPurchaseOrderTransmissionMethodCode(POTransmissionMethods.NOPRINT);
293                reqDoc.setPurchaseOrderCostSourceCode(POCostSources.ESTIMATE);
294                reqDoc.setChartOfAccountsCode("KO");
295                reqDoc.setOrganizationCode("SBSC");
296                reqDoc.setDeliveryCampusCode("KO");
297                reqDoc.setDeliveryCountryCode("US");
298                reqDoc.setRequestorPersonName("WATSON,TERRENCE G");
299                reqDoc.setRequestorPersonEmailAddress("tw@kuali.org");
300                reqDoc.setRequestorPersonPhoneNumber("812-555-5555");
301                reqDoc.setDeliveryBuildingCode("ADMN");
302                reqDoc.setDeliveryBuildingName("Administration");
303                reqDoc.setDeliveryBuildingRoomNumber("100");
304                reqDoc.setDeliveryBuildingLine1Address("98 smart street");
305                reqDoc.setDeliveryCityName("brainy");
306                reqDoc.setDeliveryStateCode("CA");
307                reqDoc.setDeliveryPostalCode("46202");
308                reqDoc.setDeliveryToName("front desk");
309                reqDoc.setBillingName("THE UNIVERSITY");
310                reqDoc.setBillingLine1Address("ACCOUNTS PAYABLE");
311                reqDoc.setBillingCityName("BUTTER NUT");
312                reqDoc.setBillingStateCode("SC");
313                reqDoc.setBillingPostalCode("47402");
314                reqDoc.setBillingCountryCode("US");
315                reqDoc.setBillingPhoneNumber("111-111-1111");
316                reqDoc.setPurchaseOrderAutomaticIndicator(false);
317                reqDoc.setStatusCode(RequisitionStatuses.IN_PROCESS);
318                reqDoc.setVendorHeaderGeneratedIdentifier(1016);
319                reqDoc.setVendorDetailAssignedIdentifier(0);
320                reqDoc.setVendorName("PHYSIK INSTRUMENT L.P.");
321                reqDoc.setVendorLine1Address("16 AUBURN ST");
322                reqDoc.setVendorCityName("AUBURN");
323                reqDoc.setVendorStateCode("MA");
324                reqDoc.setVendorPostalCode("01501");
325                reqDoc.setVendorCountryCode("US");
326                reqDoc.setUseTaxIndicator(false);
327    
328                // set item attributes
329                RequisitionItem item1 = new RequisitionItem();
330                item1.setItemLineNumber(new Integer(1));
331                item1.setItemUnitOfMeasureCode("");
332                item1.setItemCatalogNumber("");
333                item1.setItemDescription("consulting");
334                item1.setItemUnitPrice(new BigDecimal(5000));
335                item1.setItemTypeCode("SRVC");
336                item1.setItemQuantity(null);
337                item1.setExtendedPrice(new KualiDecimal(5000));
338                item1.setItemAssignedToTradeInIndicator(false);
339    
340                // set accounting line attributes
341                RequisitionAccount account1 = new RequisitionAccount();
342                account1.setPostingYear(2004);
343                account1.setChartOfAccountsCode("BL");
344                account1.setAccountNumber("1023200");
345                account1.setFinancialObjectCode("4078");
346                account1.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
347                account1.setAmount(new KualiDecimal("100"));
348                account1.setAccountLinePercent(new BigDecimal("100"));
349    
350                item1.getSourceAccountingLines().add(account1);
351                reqDoc.getItems().add(item1);
352                reqDoc.fixItemReferences();
353            }
354            catch (WorkflowException e1) {
355                e1.printStackTrace();
356            }
357            return reqDoc;
358        }
359    
360        public RequisitionDocument populateCapitalAsset_Individual_WithAddresses_Document() {
361            RequisitionDocument reqDoc = null;
362            try {
363                reqDoc = (RequisitionDocument) documentService.getNewDocument(RequisitionDocument.class);
364    
365                // set doc attributes
366                reqDoc.getDocumentHeader().setExplanation("batch created quantity document for cams");
367                DocumentHeader documentHeader = reqDoc.getDocumentHeader();
368                documentHeader.setDocumentDescription("batch created quantity document for cams");
369                reqDoc.setDocumentFundingSourceCode("INST");
370                reqDoc.setRequisitionSourceCode(RequisitionSources.STANDARD_ORDER);
371                reqDoc.setPurchaseOrderTransmissionMethodCode(POTransmissionMethods.NOPRINT);
372                reqDoc.setPurchaseOrderCostSourceCode(POCostSources.ESTIMATE);
373                reqDoc.setChartOfAccountsCode("UA");
374                reqDoc.setOrganizationCode("VPIT");
375                reqDoc.setDeliveryCampusCode("KO");
376                reqDoc.setRequestorPersonName("WATSON,TERRENCE G");
377                reqDoc.setRequestorPersonEmailAddress("tw@kuali.org");
378                reqDoc.setRequestorPersonPhoneNumber("812-555-5555");
379                reqDoc.setDeliveryBuildingCode("ADMN");
380                reqDoc.setDeliveryBuildingName("Administration");
381                reqDoc.setDeliveryBuildingRoomNumber("100");
382                reqDoc.setDeliveryBuildingLine1Address("98 smart street");
383                reqDoc.setDeliveryCityName("brainy");
384                reqDoc.setDeliveryStateCode("CA");
385                reqDoc.setDeliveryPostalCode("46202");
386                reqDoc.setDeliveryToName("front desk");
387                reqDoc.setBillingName("THE UNIVERSITY");
388                reqDoc.setBillingLine1Address("ACCOUNTS PAYABLE");
389                reqDoc.setBillingCityName("BUTTER NUT");
390                reqDoc.setBillingStateCode("SC");
391                reqDoc.setBillingPostalCode("47402");
392                reqDoc.setBillingCountryCode("US");
393                reqDoc.setBillingPhoneNumber("111-111-1111");
394                reqDoc.setPurchaseOrderAutomaticIndicator(false);
395                reqDoc.setStatusCode(RequisitionStatuses.IN_PROCESS);
396                reqDoc.setVendorHeaderGeneratedIdentifier(1002);
397                reqDoc.setVendorDetailAssignedIdentifier(0);
398                reqDoc.setVendorName("MK CORPORATION ACTIVE");
399                reqDoc.setVendorLine1Address("3984 SOUTH ST");
400                reqDoc.setVendorCityName("SPRINGFIELD");
401                reqDoc.setVendorStateCode("IL");
402                reqDoc.setVendorPostalCode("33555");
403                reqDoc.setVendorCountryCode("US");
404                reqDoc.setUseTaxIndicator(false);
405    
406                // set item attributes
407                RequisitionItem item1 = new RequisitionItem();
408                item1.setItemLineNumber(new Integer(1));
409                item1.setItemUnitOfMeasureCode("EA");
410                item1.setItemCatalogNumber("P10M980");
411                item1.setItemDescription("Gas Chromatograph");
412                item1.setItemUnitPrice(new BigDecimal(5000));
413                item1.setItemTypeCode("ITEM");
414                item1.setItemQuantity(new KualiDecimal(2.00));
415                item1.setExtendedPrice(new KualiDecimal(10000));
416                item1.setItemAssignedToTradeInIndicator(false);
417                item1.refreshReferenceObject("itemType");
418    
419                // set accounting line attributes
420                RequisitionAccount account1 = new RequisitionAccount();
421                account1.setPostingYear(2004);
422                account1.setChartOfAccountsCode("BL");
423                account1.setAccountNumber("1023200");
424                account1.setFinancialObjectCode("7000");
425                account1.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
426                account1.setAmount(new KualiDecimal("10000"));
427                account1.setAccountLinePercent(new BigDecimal("100"));
428    
429                item1.getSourceAccountingLines().add(account1);
430                reqDoc.getItems().add(item1);
431                reqDoc.fixItemReferences();
432    
433                reqDoc.setCapitalAssetSystemStateCode("NEW");
434                reqDoc.setCapitalAssetSystemTypeCode("IND");
435    
436                // Save here because auto-generated IDs will be needed later.
437                purapService.saveDocumentNoValidation(reqDoc);
438                List<PurchasingCapitalAssetItem> purchasingCapitalAssetItems = new TypedArrayList(reqDoc.getPurchasingCapitalAssetItemClass());
439                RequisitionCapitalAssetItem capitalAssetItem = (RequisitionCapitalAssetItem) requisitionService.createCamsItem(reqDoc, item1);
440                capitalAssetItem.setCapitalAssetTransactionTypeCode("NEW");
441    
442                RequisitionCapitalAssetSystem system = (RequisitionCapitalAssetSystem) capitalAssetItem.getPurchasingCapitalAssetSystem();
443                system.setCapitalAssetNoteText("CA Notes go here");
444                system.setCapitalAssetNotReceivedCurrentFiscalYearIndicator(false);
445                system.setCapitalAssetManufacturerName("MK CORPORATION ACTIVE");
446                system.setCapitalAssetTypeCode("07034");
447                system.setCapitalAssetModelDescription("XXYYZZ");
448    
449                List<CapitalAssetLocation> locations = new TypedArrayList(system.getCapitalAssetLocationClass());
450    
451                RequisitionCapitalAssetLocation loc1 = new RequisitionCapitalAssetLocation();
452                loc1.setCapitalAssetSystemIdentifier(system.getCapitalAssetSystemIdentifier());
453                loc1.setItemQuantity(new KualiDecimal("1.00"));
454                loc1.setCampusCode("BL");
455                loc1.setBuildingCode("BL001");
456                loc1.setCapitalAssetLine1Address("211 S Indiana Ave");
457                loc1.setBuildingRoomNumber("001");
458                loc1.setCapitalAssetCityName("Bloomington");
459                loc1.setCapitalAssetStateCode("IN");
460                loc1.setCapitalAssetPostalCode("47405-7001");
461                loc1.setCapitalAssetCountryCode("US");
462                locations.add(loc1);
463    
464                RequisitionCapitalAssetLocation loc2 = new RequisitionCapitalAssetLocation();
465                loc2.setCapitalAssetSystemIdentifier(system.getCapitalAssetSystemIdentifier());
466                loc2.setItemQuantity(new KualiDecimal("1.00"));
467                loc2.setCampusCode("BL");
468                loc2.setBuildingCode("BL001");
469                loc2.setCapitalAssetLine1Address("211 S Indiana Ave");
470                loc2.setBuildingRoomNumber("001A");
471                loc2.setCapitalAssetCityName("Bloomington");
472                loc2.setCapitalAssetStateCode("IN");
473                loc2.setCapitalAssetPostalCode("47405-7001");
474                loc2.setCapitalAssetCountryCode("US");
475                locations.add(loc2);
476    
477                system.setCapitalAssetLocations(locations);
478    
479                purchasingCapitalAssetItems.add(capitalAssetItem);
480                reqDoc.setPurchasingCapitalAssetItems(purchasingCapitalAssetItems);
481            }
482            catch (WorkflowException e1) {
483                e1.printStackTrace();
484            }
485            return reqDoc;
486        }
487    
488        private RequisitionDocument populateCapitalAsset_Individual_Unfilled_Document() {
489            RequisitionDocument reqDoc = null;
490            try {
491                reqDoc = (RequisitionDocument) documentService.getNewDocument(RequisitionDocument.class);
492    
493                // set doc attributes
494                reqDoc.getDocumentHeader().setExplanation("batch created quantity document BAS");
495                DocumentHeader documentHeader = reqDoc.getDocumentHeader();
496                documentHeader.setDocumentDescription("batch created quantity document BAS");
497                reqDoc.setDocumentFundingSourceCode("INST");
498                reqDoc.setRequisitionSourceCode(RequisitionSources.STANDARD_ORDER);
499                reqDoc.setPurchaseOrderTransmissionMethodCode(POTransmissionMethods.NOPRINT);
500                reqDoc.setPurchaseOrderCostSourceCode(POCostSources.ESTIMATE);
501                reqDoc.setChartOfAccountsCode("UA");
502                reqDoc.setOrganizationCode("VPIT");
503                reqDoc.setDeliveryCampusCode("KO");
504                reqDoc.setRequestorPersonName("WATSON,TERRENCE G");
505                reqDoc.setRequestorPersonEmailAddress("tw@kuali.org");
506                reqDoc.setRequestorPersonPhoneNumber("812-555-5555");
507                reqDoc.setDeliveryBuildingCode("ADMN");
508                reqDoc.setDeliveryBuildingName("Administration");
509                reqDoc.setDeliveryBuildingRoomNumber("100");
510                reqDoc.setDeliveryBuildingLine1Address("98 smart street");
511                reqDoc.setDeliveryCityName("brainy");
512                reqDoc.setDeliveryStateCode("CA");
513                reqDoc.setDeliveryPostalCode("46202");
514                reqDoc.setDeliveryToName("front desk");
515                reqDoc.setBillingName("THE UNIVERSITY");
516                reqDoc.setBillingLine1Address("ACCOUNTS PAYABLE");
517                reqDoc.setBillingCityName("BUTTER NUT");
518                reqDoc.setBillingStateCode("SC");
519                reqDoc.setBillingPostalCode("47402");
520                reqDoc.setBillingCountryCode("US");
521                reqDoc.setBillingPhoneNumber("111-111-1111");
522                reqDoc.setPurchaseOrderAutomaticIndicator(false);
523                reqDoc.setStatusCode(RequisitionStatuses.IN_PROCESS);
524                reqDoc.setVendorHeaderGeneratedIdentifier(1002);
525                reqDoc.setVendorDetailAssignedIdentifier(0);
526                reqDoc.setVendorName("MK CORPORATION ACTIVE");
527                reqDoc.setVendorLine1Address("3984 SOUTH ST");
528                reqDoc.setVendorCityName("SPRINGFIELD");
529                reqDoc.setVendorStateCode("IL");
530                reqDoc.setVendorPostalCode("33555");
531                reqDoc.setVendorCountryCode("US");
532                reqDoc.setUseTaxIndicator(false);
533    
534                // set item attributes
535                RequisitionItem item1 = new RequisitionItem();
536                item1.setItemLineNumber(new Integer(1));
537                item1.setItemUnitOfMeasureCode("EA");
538                item1.setItemCatalogNumber("");
539                item1.setItemDescription("Gas Chromatograph");
540                item1.setItemUnitPrice(new BigDecimal(6000));
541                item1.setItemTypeCode("ITEM");
542                item1.setItemQuantity(new KualiDecimal(1.00));
543                item1.setExtendedPrice(new KualiDecimal(6000));
544                item1.setItemAssignedToTradeInIndicator(false);
545    
546                // set accounting line attributes
547                RequisitionAccount account1 = new RequisitionAccount();
548                account1.setPostingYear(2004);
549                account1.setChartOfAccountsCode("BL");
550                account1.setAccountNumber("1023200");
551                account1.setFinancialObjectCode("7000");
552                account1.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
553                account1.setAmount(new KualiDecimal("10000"));
554                account1.setAccountLinePercent(new BigDecimal("100"));
555    
556                item1.getSourceAccountingLines().add(account1);
557                reqDoc.getItems().add(item1);
558                reqDoc.fixItemReferences();
559    
560                reqDoc.setCapitalAssetSystemStateCode("NEW");
561                reqDoc.setCapitalAssetSystemTypeCode("IND");
562    
563                // Save here because auto-generated IDs will be needed later.
564                purapService.saveDocumentNoValidation(reqDoc);
565                List<PurchasingCapitalAssetItem> purchasingCapitalAssetItems = new TypedArrayList(reqDoc.getPurchasingCapitalAssetItemClass());
566                RequisitionCapitalAssetItem capitalAssetItem = (RequisitionCapitalAssetItem) requisitionService.createCamsItem(reqDoc, item1);
567                capitalAssetItem.setCapitalAssetTransactionTypeCode("NEW");
568    
569                RequisitionCapitalAssetSystem system = (RequisitionCapitalAssetSystem) capitalAssetItem.getPurchasingCapitalAssetSystem();
570                system.setCapitalAssetNoteText("");
571                system.setCapitalAssetNotReceivedCurrentFiscalYearIndicator(false);
572                system.setCapitalAssetManufacturerName("");
573                system.setCapitalAssetTypeCode("");
574                system.setCapitalAssetModelDescription("");
575    
576                purchasingCapitalAssetItems.add(capitalAssetItem);
577                reqDoc.setPurchasingCapitalAssetItems(purchasingCapitalAssetItems);
578            }
579            catch (WorkflowException e1) {
580                e1.printStackTrace();
581            }
582            return reqDoc;
583        }
584    
585        /**
586         * Sets a Run parameter that tells the step that it has already run and it does not need to run again.
587         */
588        private void setInitiatedRunParameter() {
589            // First, see if we can find an existing Parameter object with this key.
590            Parameter runIndicatorParameter = (Parameter) boService.findByPrimaryKey(Parameter.class, this.buildRunParameterSearchKeyMap());
591            if (runIndicatorParameter == null) {
592                runIndicatorParameter = new Parameter();
593                runIndicatorParameter.setVersionNumber(new Long(1));
594                runIndicatorParameter.setParameterNamespaceCode(PurapConstants.PURAP_NAMESPACE);
595                runIndicatorParameter.setParameterDetailTypeCode(RUN_INDICATOR_PARAMETER_NAMESPACE_STEP);
596                runIndicatorParameter.setParameterName(Job.STEP_RUN_PARM_NM);
597                runIndicatorParameter.setParameterDescription(RUN_INDICATOR_PARAMETER_DESCRIPTION);
598                runIndicatorParameter.setParameterConstraintCode(RUN_INDICATOR_PARAMETER_ALLOWED);
599                runIndicatorParameter.setParameterTypeCode(RUN_INDICATOR_PARAMETER_TYPE);
600                runIndicatorParameter.setParameterApplicationNamespaceCode(KFSConstants.APPLICATION_NAMESPACE_CODE);
601            }
602            runIndicatorParameter.setParameterValue(RUN_INDICATOR_PARAMETER_VALUE);
603            boService.save(runIndicatorParameter);
604        }
605    
606        /**
607         * Used by setInitiatedRunParameter to build a Map of search keys to obtain the exact needed Run parameter from the database.
608         * 
609         * @return A Map<String,Object> where the Objects are the attributes of the Run parameter
610         */
611        private Map<String, Object> buildRunParameterSearchKeyMap() {
612            Map<String, Object> pkMapForParameter = new HashMap<String, Object>();
613    
614            // Set up a list of all the field names and values of the fields in the Parameter object.
615            Map<String, Object> fieldNamesValuesForParameter = new HashMap<String, Object>();
616            fieldNamesValuesForParameter.put("parameterNamespaceCode", PurapConstants.PURAP_NAMESPACE);
617            fieldNamesValuesForParameter.put("parameterDetailTypeCode", RUN_INDICATOR_PARAMETER_NAMESPACE_STEP);
618            fieldNamesValuesForParameter.put("parameterName", Job.STEP_RUN_PARM_NM);
619            fieldNamesValuesForParameter.put("parameterConstraintCode", RUN_INDICATOR_PARAMETER_ALLOWED);
620            fieldNamesValuesForParameter.put("parameterTypeCode", RUN_INDICATOR_PARAMETER_TYPE);
621    
622            // get the primary keys and assign them to values
623            List<String> parameterPKFields = psService.getPrimaryKeys(Parameter.class);
624            for (String pkFieldName : parameterPKFields) {
625                pkMapForParameter.put(pkFieldName, fieldNamesValuesForParameter.get(pkFieldName));
626            }
627            return pkMapForParameter;
628        }
629    
630        private ContractManagerAssignmentDocument createAndRouteContractManagerAssignmentDocument(RequisitionDocument reqDoc) {
631            ContractManagerAssignmentDocument acmDoc = null;
632            try {
633                acmDoc = (ContractManagerAssignmentDocument) documentService.getNewDocument(ContractManagerAssignmentDocument.class);
634                List<ContractManagerAssignmentDetail> contractManagerAssignmentDetails = new TypedArrayList(ContractManagerAssignmentDetail.class);
635                ContractManagerAssignmentDetail detail = new ContractManagerAssignmentDetail(acmDoc, reqDoc);
636                detail.setContractManagerCode(new Integer("10"));
637                detail.refreshReferenceObject("contractManager");
638                contractManagerAssignmentDetails.add(detail);
639                acmDoc.setContractManagerAssignmentDetailss(contractManagerAssignmentDetails);
640                acmDoc.getDocumentHeader().setDocumentDescription("batch-created");
641                documentService.routeDocument(acmDoc, "Routing batch-created Contract Manager Assignment Document", null);
642                ChangeWaiter waiter = new ChangeWaiter(documentService, acmDoc.getDocumentNumber(), "F");
643                try {
644                    waiter.waitUntilChange(waiter, ROUTE_TO_FINAL_SECONDS_LIMIT, 5);
645                }
646                catch (Exception e) {
647                    throw new RuntimeException("ContractManagerAssignmentDocument timed out in routing to final.");
648                }
649            }
650            catch (WorkflowException we) {
651                we.printStackTrace();
652            }
653            catch (ValidationException ve) {
654                ve.printStackTrace();
655            }
656            return acmDoc;
657        }
658    
659        private void createAndRoutePurchaseOrderDocument(RequisitionDocument reqDoc, ContractManagerAssignmentDocument acmDoc) {
660    
661            List<PurchaseOrderView> poViews = reqDoc.getRelatedViews().getRelatedPurchaseOrderViews();
662            if ((poViews != null) && (poViews.size() >= 1)) {
663                // There should be only one related PO at this point, so get that one and route it.
664                PurchaseOrderView poView = poViews.get(0);
665                String relatedPOWorkflowDocumentId = poView.getDocumentNumber();
666                PurchaseOrderDocument poDoc = null;
667                try {
668                    poDoc = (PurchaseOrderDocument) documentService.getByDocumentHeaderId(relatedPOWorkflowDocumentId);
669                    documentService.blanketApproveDocument(poDoc, "auto-routing: Test Requisition Job", null);
670                    ChangeWaiter waiter = new ChangeWaiter(documentService, poDoc.getDocumentNumber(), "F");
671                    try {
672                        waiter.waitUntilChange(waiter, ROUTE_TO_FINAL_SECONDS_LIMIT, 5);
673                    }
674                    catch (Exception e) {
675                        throw new RuntimeException("ContractManagerAssignmentDocument timed out in routing to final.");
676                    }
677                }
678                catch (WorkflowException e) {
679                    e.printStackTrace();
680                }
681                catch (ValidationException ve) {
682                    ve.printStackTrace();
683                }
684            }
685        }
686    
687        public DocumentService getDocumentService() {
688            return documentService;
689        }
690    
691        public void setDocumentService(DocumentService documentService) {
692            this.documentService = documentService;
693        }
694    
695        public RequisitionService getRequisitionService() {
696            return requisitionService;
697        }
698    
699        public void setRequisitionService(RequisitionService requisitionService) {
700            this.requisitionService = requisitionService;
701        }
702    
703        public PurapService getPurapService() {
704            return purapService;
705        }
706    
707        public void setPurapService(PurapService purapService) {
708            this.purapService = purapService;
709        }
710    
711        public BusinessObjectService getBoService() {
712            return boService;
713        }
714    
715        public void setBoService(BusinessObjectService boService) {
716            this.boService = boService;
717        }
718    
719        public PersistenceStructureService getPsService() {
720            return psService;
721        }
722    
723        public void setPsService(PersistenceStructureService psService) {
724            this.psService = psService;
725        }
726    
727        /**
728         * Performs the same function as DocumentWorkflowStatusMonitor, which is a test utility, and cannot be used outside that
729         * package. Allows us to wait until a change of Workflow status has occurred.
730         */
731        private class ChangeWaiter {
732    
733            final DocumentService documentService;
734            final private String docHeaderId;
735            final private String[] desiredWorkflowStates;
736    
737            public ChangeWaiter(DocumentService documentService, String docHeaderId, String desiredWorkflowStatus) {
738                this.documentService = documentService;
739                this.docHeaderId = docHeaderId;
740                this.desiredWorkflowStates = new String[] { desiredWorkflowStatus };
741            }
742    
743            public boolean valueChanged() throws Exception {
744                Document d = documentService.getByDocumentHeaderId(docHeaderId.toString());
745    
746                String currentStatus = d.getDocumentHeader().getWorkflowDocument().getRouteHeader().getDocRouteStatus();
747    
748                for (int i = 0; i < desiredWorkflowStates.length; i++) {
749                    if (StringUtils.equals(desiredWorkflowStates[i], currentStatus)) {
750                        return true;
751                    }
752                }
753                return false;
754            }
755    
756            public boolean waitUntilChange(ChangeWaiter monitor, int maxWaitSeconds, int pauseSeconds) throws Exception {
757                long maxWaitMs = maxWaitSeconds * 1000;
758                long pauseMs = pauseSeconds * 1000;
759    
760                boolean valueChanged = false;
761                boolean interrupted = false;
762                long startTimeMs = System.currentTimeMillis();
763                long endTimeMs = startTimeMs + maxWaitMs;
764    
765                Thread.sleep(pauseMs / 10); // the first time through, sleep a fraction of the specified time
766                valueChanged = monitor.valueChanged();
767                LOG.debug("starting wait loop");
768                while (!interrupted && !valueChanged && (System.currentTimeMillis() < endTimeMs)) {
769                    try {
770                        if (LOG.isDebugEnabled()) {
771                            LOG.debug("sleeping for " + pauseMs + " ms");
772                        }
773                        Thread.sleep(pauseMs);
774                    }
775                    catch (InterruptedException e) {
776                        interrupted = true;
777                    }
778                    LOG.debug("checking wait loop sentinel");
779                    valueChanged = monitor.valueChanged();
780                }
781                LOG.debug("finished wait loop (" + valueChanged + ")");
782    
783                return valueChanged;
784            }
785        }
786    
787    }