View Javadoc
1   /*
2               NoteService noteService = KRADServiceLocator.getNoteService();
3               notes = noteService.getByRemoteObjectId(this.getBusinessObject().getObjectId());
4    * Copyright 2007 The Kuali Foundation
5    * 
6    * Licensed under the Educational Community License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * 
10   * http://www.opensource.org/licenses/ecl2.php
11   * 
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.kuali.ole.vnd.document;
19  
20  import java.sql.Timestamp;
21  import java.util.*;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.kuali.ole.OLEConstants;
25  import org.kuali.ole.docstore.common.client.DocstoreClientLocator;
26  import org.kuali.ole.docstore.common.search.*;
27  import org.kuali.ole.docstore.engine.service.storage.rdbms.pojo.HoldingsRecord;
28  import org.kuali.ole.select.gokb.OleGokbOrganization;
29  import org.kuali.ole.select.gokb.OleGokbReview;
30  import org.kuali.ole.sys.context.SpringContext;
31  import org.kuali.ole.sys.document.FinancialSystemMaintainable;
32  import org.kuali.ole.vnd.VendorConstants;
33  import org.kuali.ole.vnd.VendorKeyConstants;
34  import org.kuali.ole.vnd.VendorParameterConstants;
35  import org.kuali.ole.vnd.VendorPropertyConstants;
36  import org.kuali.ole.vnd.VendorUtils;
37  import org.kuali.ole.vnd.businessobject.*;
38  import org.kuali.ole.vnd.document.service.VendorService;
39  import org.kuali.rice.core.api.datetime.DateTimeService;
40  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
41  import org.kuali.rice.kew.api.WorkflowDocument;
42  import org.kuali.rice.kim.api.identity.Person;
43  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44  import org.kuali.rice.kns.document.MaintenanceDocument;
45  import org.kuali.rice.kns.maintenance.Maintainable;
46  import org.kuali.rice.krad.bo.DocumentHeader;
47  import org.kuali.rice.krad.bo.Note;
48  import org.kuali.rice.krad.bo.PersistableBusinessObject;
49  import org.kuali.rice.krad.maintenance.MaintenanceLock;
50  import org.kuali.rice.krad.service.BusinessObjectService;
51  import org.kuali.rice.krad.service.KRADServiceLocator;
52  import org.kuali.rice.krad.service.NoteService;
53  import org.kuali.rice.krad.util.GlobalVariables;
54  import org.kuali.rice.krad.util.ObjectUtils;
55  
56  public class VendorMaintainableImpl extends FinancialSystemMaintainable {
57      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(VendorMaintainableImpl.class);
58  
59      private DocstoreClientLocator docstoreClientLocator;
60      public DocstoreClientLocator getDocstoreClientLocator() {
61          if (null == docstoreClientLocator) {
62              return SpringContext.getBean(DocstoreClientLocator.class);
63          }
64          return docstoreClientLocator;
65      }
66  
67      /**
68       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#setGenerateDefaultValues(boolean)
69       */
70  	@Override
71      public void setGenerateDefaultValues(String docTypeName) {
72          super.setGenerateDefaultValues(docTypeName);
73          
74          List<Note> notes = new ArrayList<Note>();
75  
76          if (getBusinessObject().getObjectId() != null) {
77              NoteService noteService = KRADServiceLocator.getNoteService();
78              notes = noteService.getByRemoteObjectId(this.getBusinessObject().getObjectId());
79                    
80              if (notes.isEmpty()) {
81                  notes.add(getNewBoNoteForAdding(VendorConstants.VendorCreateAndUpdateNotePrefixes.ADD));
82              }
83          }
84      }
85  
86      /**
87       * Overrides the kuali default documents title with a Vendor-specific document title style
88       * 
89       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#getDocumentTitle(org.kuali.rice.kns.document.MaintenanceDocument)
90       */
91      @Override
92      public String getDocumentTitle(MaintenanceDocument document) {
93          String documentTitle = "";
94          // Check if we are choosing to override the Kuali default document title.
95          if (SpringContext.getBean(ParameterService.class).getParameterValueAsBoolean(VendorDetail.class, VendorParameterConstants.OVERRIDE_VENDOR_DOC_TITLE)) {
96              // We are overriding the standard with a Vendor-specific document title style.
97              if (document.isOldBusinessObjectInDocument()) {
98                  documentTitle = "Edit Vendor - ";
99              }
100             else {
101                 documentTitle = "New Vendor - ";
102             }
103 
104             try {
105                 Person initUser = KimApiServiceLocator.getPersonService().getPerson(document.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId());
106                 documentTitle += initUser.getCampusCode();
107             }
108             catch (Exception e) {
109                 throw new RuntimeException("Document Initiator not found " + e.getMessage());
110             }
111 
112             VendorDetail newBo = (VendorDetail) document.getNewMaintainableObject().getBusinessObject();
113 
114             if (StringUtils.isNotBlank(newBo.getVendorName())) {
115                 documentTitle += " '" + newBo.getVendorName() + "'";
116             } 
117             else {            
118                 if (StringUtils.isNotBlank(newBo.getVendorFirstName())) {
119                     documentTitle += " '" + newBo.getVendorFirstName() + " ";
120                     if (StringUtils.isBlank(newBo.getVendorLastName())) {
121                         documentTitle += "'";
122                     }
123                 }
124                 
125                 if (StringUtils.isNotBlank(newBo.getVendorLastName())) {
126                     if (StringUtils.isBlank(newBo.getVendorFirstName())) {
127                         documentTitle += " '";
128                     }
129                     documentTitle += newBo.getVendorLastName() + "'";
130                 }
131             }
132 
133             if (newBo.getVendorHeader().getVendorForeignIndicator()) {
134                 documentTitle += " (F)";
135             }
136 
137             if (!newBo.isVendorParentIndicator()) {
138                 documentTitle += " (D)";
139             }
140         }
141         else { // We are using the Kuali default document title.
142             documentTitle = super.getDocumentTitle(document);
143         }
144         return documentTitle;
145     }
146 
147     @Override
148     public void doRouteStatusChange(DocumentHeader header) {
149         super.doRouteStatusChange(header);
150         VendorDetail vendorDetail = (VendorDetail) getBusinessObject();
151         WorkflowDocument workflowDoc = header.getWorkflowDocument();
152 
153         // This code is only executed when the final approval occurs
154         if (workflowDoc.isProcessed()) {
155             // This id and versionNumber null check is needed here since those fields are always null for a fresh maintenance doc.
156             if (vendorDetail.isVendorParentIndicator() && vendorDetail.getVendorHeaderGeneratedIdentifier() != null) { 
157                 VendorDetail previousParent = SpringContext.getBean(VendorService.class).getParentVendor(vendorDetail.getVendorHeaderGeneratedIdentifier());
158                 // We'll only need to do the following if the previousParent is not the same as the current vendorDetail, because
159                 // the following lines are for vendor parent indicator changes.
160                 if (vendorDetail.getVendorDetailAssignedIdentifier() == null || 
161                         previousParent.getVendorHeaderGeneratedIdentifier().intValue() != vendorDetail.getVendorHeaderGeneratedIdentifier().intValue() || 
162                         previousParent.getVendorDetailAssignedIdentifier().intValue() != vendorDetail.getVendorDetailAssignedIdentifier().intValue()) {
163                     previousParent.setVendorParentIndicator(false);
164                     addNoteForParentIndicatorChange(vendorDetail, previousParent, header.getDocumentNumber());
165                     SpringContext.getBean(BusinessObjectService.class).save(previousParent);
166                 }
167             }
168 
169             // If this is a pre-existing parent vendor, and if the Tax Number or the Tax Type Code will change, log the change in the
170             // Tax Change table.
171             if (vendorDetail.isVendorParentIndicator()) {
172                 VendorDetail oldVendorDetail = SpringContext.getBean(VendorService.class).getVendorDetail(vendorDetail.getVendorHeaderGeneratedIdentifier(), vendorDetail.getVendorDetailAssignedIdentifier());
173                 if (ObjectUtils.isNotNull(oldVendorDetail)) {
174                     VendorHeader oldVendorHeader = oldVendorDetail.getVendorHeader();
175                     VendorHeader newVendorHeader = vendorDetail.getVendorHeader();
176 
177                     if (ObjectUtils.isNotNull(oldVendorHeader)) { // Does not apply if this is a new parent vendor.
178                         String oldVendorTaxNumber = oldVendorHeader.getVendorTaxNumber();
179                         String oldVendorTaxTypeCode = oldVendorHeader.getVendorTaxTypeCode();
180 
181                         String vendorTaxNumber = newVendorHeader.getVendorTaxNumber();
182                         String vendorTaxTypeCode = newVendorHeader.getVendorTaxTypeCode();
183 
184                         if ((!StringUtils.equals(vendorTaxNumber, oldVendorTaxNumber)) || (!StringUtils.equals(vendorTaxTypeCode, oldVendorTaxTypeCode))) {
185                             VendorTaxChange taxChange = new VendorTaxChange(vendorDetail.getVendorHeaderGeneratedIdentifier(), SpringContext.getBean(DateTimeService.class).getCurrentTimestamp(), oldVendorTaxNumber, oldVendorTaxTypeCode, GlobalVariables.getUserSession().getPerson().getPrincipalId());
186                             SpringContext.getBean(BusinessObjectService.class).save(taxChange);
187                         }
188                     }
189                 }
190             }
191 
192         }//endif isProcessed()
193     }
194     
195     /**
196      * Add a note to the previous parent vendor to denote that parent vendor indicator change had occurred.
197      * 
198      * @param newVendorDetail The current vendor
199      * @param oldVendorDetail The parent vendor of the current vendor prior to this change.
200      * @param getDocumentNumber() The document number of the document where we're attempting the parent vendor indicator change.
201      */
202     private void addNoteForParentIndicatorChange(VendorDetail newVendorDetail, VendorDetail oldVendorDetail, String docNumber) {
203         String noteText = VendorUtils.buildMessageText(VendorKeyConstants.MESSAGE_VENDOR_PARENT_TO_DIVISION, docNumber, newVendorDetail.getVendorName() + " (" + newVendorDetail.getVendorNumber() + ")");   
204         Note newBONote = new Note();
205         newBONote.setNoteText(noteText);
206         try {
207             NoteService noteService = SpringContext.getBean(NoteService.class);
208             newBONote = noteService.createNote(newBONote, oldVendorDetail, GlobalVariables.getUserSession().getPrincipalId());
209             newBONote.setNotePostedTimestampToCurrent();
210             
211             noteService.save(newBONote);
212         }
213         catch (Exception e) {
214             throw new RuntimeException("Caught Exception While Trying To Add Note to Vendor", e);
215         }
216         
217         NoteService noteService = KRADServiceLocator.getNoteService();
218         List<Note> notes = noteService.getByRemoteObjectId(oldVendorDetail.getObjectId());
219         notes.add(newBONote);
220     }
221     
222     /**
223      * Refreshes the vendorDetail. Currently we need this mainly for refreshing the soldToVendor object after returning from the
224      * lookup for a sold to vendor.
225      * 
226      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#refresh(java.lang.String, java.util.Map,
227      *      org.kuali.rice.kns.document.MaintenanceDocument)
228      */
229     @Override
230     public void refresh(String refreshCaller, Map fieldValues, MaintenanceDocument document) {
231         PersistableBusinessObject oldBo = (PersistableBusinessObject) document.getOldMaintainableObject().getBusinessObject();
232         if (ObjectUtils.isNotNull(oldBo)) {
233             oldBo.refreshNonUpdateableReferences();
234         }
235         VendorDetail newBo = (VendorDetail) document.getNewMaintainableObject().getBusinessObject();
236         // Here we have to temporarily save vendorHeader into a temp object, then put back
237         // the vendorHeader into the newBo after the refresh, so that we don't lose the
238         // values
239         VendorHeader tempHeader = newBo.getVendorHeader();
240         newBo.refreshNonUpdateableReferences();
241         newBo.setVendorHeader(tempHeader);
242         super.refresh(refreshCaller, fieldValues, document);
243     }
244 
245     /**
246      * Temporarily saves vendorHeader into a temp object, then put back the vendorHeader into the VendorDetail after the refresh, so
247      * that we don't lose the values
248      */
249     public void refreshBusinessObject() {
250         VendorDetail vd = (VendorDetail) getBusinessObject();
251         // Here we have to temporarily save vendorHeader into a temp object, then put back
252         // the vendorHeader into the VendorDetail after the refresh, so that we don't lose the
253         // values
254         VendorHeader tempHeader = vd.getVendorHeader();
255         vd.refreshNonUpdateableReferences();
256         vd.setVendorHeader(tempHeader);
257     }
258 
259 
260     /**
261      * Checks whether the vendor has already had a vendor detail assigned id. If not, it will call the private method to set the
262      * detail assigned id. The method will also call the vendorService to determine whether it should save the vendor header (i.e.
263      * if this is a parent) and will save the vendor header accordingly. This is because we are not going to save vendor header
264      * automatically along with the saving of vendor detail, so if the vendor is a parent, we have to save the vendor header
265      * separately. Restriction-related information will be changed based on whether the Vendor Restricted Indicator was changed. If
266      * the Tax Number or Tax Type code have changed, the fact will be recorded with a new record in the Tax Change table. Finally
267      * the method will call the saveBusinessObject( ) of the super class to save the vendor detail.
268      *
269      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#saveBusinessObject()
270      */
271     @Override
272     public void saveBusinessObject() {
273         VendorDetail vendorDetail = (VendorDetail) super.getBusinessObject();
274         VendorHeader vendorHeader = vendorDetail.getVendorHeader();
275         VendorEventLog eventLog = new VendorEventLog();
276         eventLog.setDate(new Timestamp(System.currentTimeMillis()));
277         eventLog.setLogTypeId("3");
278         eventLog.setUserId(GlobalVariables.getUserSession().getPrincipalId());
279         if (vendorDetail.getVendorHeaderGeneratedIdentifier() != null && vendorDetail.getVendorDetailAssignedIdentifier() != null) {
280             HashMap vendor = new HashMap();
281             vendor.put("vendorHeaderGeneratedIdentifier", vendorDetail.getVendorHeaderGeneratedIdentifier());
282             vendor.put("vendorDetailAssignedIdentifier", vendorDetail.getVendorDetailAssignedIdentifier());
283             List<VendorDetail> vendorDetails = (List<VendorDetail>) KRADServiceLocator.getBusinessObjectService().findMatching(VendorDetail.class, vendor);
284             if (vendorDetails.get(0).isActiveIndicator() && !vendorDetail.isActiveIndicator()) {
285                 eventLog.setNote("Vendor is inactive :" + vendorDetail.getVendorInactiveReasonCode());
286             }
287             if (!vendorDetails.get(0).isActiveIndicator() && vendorDetail.isActiveIndicator()) {
288                 Map vendorMap = new HashMap();
289                 vendorMap.put(OLEConstants.GOKB_ID, vendorDetail.getGokbId());
290                 vendorMap.put(OLEConstants.OlePatron.PATRON_ACTIVE_IND, vendorDetail.isActiveIndicator());
291                 List<VendorDetail> vendorDetailList = (List<VendorDetail>) KRADServiceLocator.getBusinessObjectService().findMatching(VendorDetail.class, vendorMap);
292                 if (vendorDetailList.size() < 0) {
293                     eventLog.setNote("Vendor is active :" + vendorDetail.getVendorInactiveReason().getVendorInactiveReasonDescription());
294                     vendorDetail.getEventLogs().add(eventLog);
295                 }
296             }
297             if(vendorDetail.getGokbId()!=null && !vendorDetail.getGokbId().equals(vendorDetail.getOldGokbId())){
298                 eventLog.setNote("GOKb :" + vendorDetail.getGokbId() + " linked to Document");
299                 HashMap organization = new HashMap();
300                 organization.put("gokbOrganizationId",vendorDetail.getGokbId());
301                 List<OleGokbOrganization> oleGokbOrganizations = (List<OleGokbOrganization>)KRADServiceLocator.getBusinessObjectService().findMatching(OleGokbOrganization.class,organization);
302                 if(org.apache.commons.collections.CollectionUtils.isNotEmpty(oleGokbOrganizations) && StringUtils.isNotBlank(oleGokbOrganizations.get(0).getVariantName())){
303                     VendorAlias alias = new VendorAlias();
304                     alias.setVendorAliasName(oleGokbOrganizations.get(0).getVariantName());
305                     alias.setGokbVendorAliasInd(true);
306                     alias.setActive(true);
307                     vendorDetail.getVendorAliases().add(alias);
308                 }
309                 vendorDetail.getEventLogs().add(eventLog);
310             }
311         }else if(vendorDetail.getVendorDetailAssignedIdentifier() == null){
312             eventLog.setNote("Created Vendor ");
313             vendorDetail.getEventLogs().add(eventLog);
314         }
315         // Update miscellaneous information and save the Vendor Header if this is a parent vendor.
316         setVendorName(vendorDetail);
317         vendorHeader.setVendorHeaderGeneratedIdentifier(vendorDetail.getVendorHeaderGeneratedIdentifier());
318         if (ObjectUtils.isNull(vendorDetail.getVendorDetailAssignedIdentifier())) {
319             setDetailAssignedId(vendorDetail);
320         }
321         if (vendorDetail.isVendorParentIndicator()) {
322             SpringContext.getBean(VendorService.class).saveVendorHeader(vendorDetail);
323         }
324 
325         List<VendorContact> vendorContacts = vendorDetail.getVendorContacts();
326 
327         Map<Integer, List<VendorContactPhoneNumber>> vendorContactPhoneNumberMap = vendorDetail.getVendorContactPhoneNumberMap();
328         for (Iterator<Integer> vendorContactIterator = vendorContactPhoneNumberMap.keySet().iterator(); vendorContactIterator.hasNext(); ) {
329             Integer key = vendorContactIterator.next();
330             VendorContact vendorContact = vendorContacts.get(key);
331             vendorContact.setVendorContactPhoneNumbers(vendorContactPhoneNumberMap.get(key));
332         }
333 
334 
335         super.saveBusinessObject();
336     }
337 
338     @Override
339     public void processAfterRetrieve() {
340         VendorDetail vendorDetail = (VendorDetail) getBusinessObject();
341         Map map = new HashMap();
342         map.put("vendorHeaderGeneratedIdentifier", vendorDetail.getVendorHeaderGeneratedIdentifier());
343         List<VendorEventLog> vendorEventLogs = (List<VendorEventLog>) getBusinessObjectService().findMatching(VendorEventLog.class,map);
344         vendorDetail.setEventLogs(vendorEventLogs);
345         super.processAfterRetrieve();
346     }
347 
348 
349     public List getSections(MaintenanceDocument document, Maintainable oldMaintainable) {
350         ArrayList sections = new ArrayList();
351         ((VendorDetail)document.getOldMaintainableObject().getBusinessObject()).setEventLogs(((VendorDetail) document.getNewMaintainableObject().getBusinessObject()).getEventLogs());
352         sections.addAll(this.getCoreSections(document, oldMaintainable));
353         return sections;
354     }
355 
356 
357 
358     /**
359      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterEdit()
360      */
361     @Override
362     public void processAfterEdit( MaintenanceDocument document, Map<String,String[]> parameters ) {
363 
364         List<Note> notes = new ArrayList<Note>();
365         if (document.getOldMaintainableObject().getBusinessObject().getObjectId() != null) {
366             NoteService noteService = KRADServiceLocator.getNoteService();
367             notes = noteService.getByRemoteObjectId(this.getBusinessObject().getObjectId());
368         }
369         setVendorCreateAndUpdateNote(notes, VendorConstants.VendorCreateAndUpdateNotePrefixes.CHANGE);
370         document.setNotes(notes);
371         VendorDetail vendorDetail = (VendorDetail) document.getNewMaintainableObject().getBusinessObject();
372         if(vendorDetail.getGokbId()!=null){
373             vendorDetail.setOldGokbId(vendorDetail.getGokbId());
374         Map hash = new HashMap();
375             hash.put("publisherId",vendorDetail.getGokbId());
376             List<HoldingsRecord> holdingsRecords = (List<HoldingsRecord>) getBusinessObjectService().findMatching(HoldingsRecord.class,hash);
377             if(holdingsRecords.size()>0){
378                 vendorDetail.setLinkedToEHoldings(true);
379             }else{
380                 vendorDetail.setLinkedToEHoldings(false);
381             }
382         }
383         super.processAfterEdit(document, parameters);
384     }
385 
386     /**
387      * Checks whether the previous note was an "Add" with the same document number as this one
388      * 
389      * @param notes List of exisiting notes.
390      * @param prefix String to determine if it is a note "Add" or a note "Change"
391      */
392     private void setVendorCreateAndUpdateNote(List<Note> notes, String prefix) {
393         boolean shouldAddNote = true;
394         
395         if (prefix.equals(VendorConstants.VendorCreateAndUpdateNotePrefixes.CHANGE)) {
396             // Check whether the previous note was an "Add" with the same document number as this one
397             if (!notes.isEmpty()) {
398                 Note previousNote = notes.get(notes.size() - 1 );
399                 if (previousNote.getNoteText().contains(getDocumentNumber())) {
400                     shouldAddNote = false;
401                 }
402             }
403         }
404         if (shouldAddNote) {
405             notes.add(getNewBoNoteForAdding(prefix));
406         }
407     }
408 
409     /**
410      * creates a new bo note and sets the timestamp.
411      * 
412      * @return a newly created note
413      */
414     protected Note getNewBoNoteForAdding(String prefix) {
415         Note newBoNote = new Note();
416         newBoNote.setNoteText(prefix + " vendor document ID " + getDocumentNumber());
417         newBoNote.setNotePostedTimestampToCurrent();
418        
419             try {
420             newBoNote = SpringContext.getBean(NoteService.class).createNote(newBoNote, this.getBusinessObject(), GlobalVariables.getUserSession().getPrincipalId());
421             }
422             catch (Exception e) {
423                 throw new RuntimeException("Caught Exception While Trying To Add Note to Vendor", e);
424             }
425         
426         return newBoNote;
427     }
428 
429     /**
430      * Concatenates the vendorLastName and a delimiter and the vendorFirstName fields into vendorName field of the vendorDetail
431      * object.
432      * 
433      * @param vendorDetail VendorDetail The vendor whose name field we are trying to assign
434      */
435     private void setVendorName(VendorDetail vendorDetail) {
436         if (vendorDetail.isVendorFirstLastNameIndicator()) {
437             vendorDetail.setVendorName(vendorDetail.getVendorLastName() + VendorConstants.NAME_DELIM + vendorDetail.getVendorFirstName());
438         }
439     }
440 
441     /**
442      * If the vendorFirstLastNameIndicator is true, this method will set the vendor first name and vendor last name fields from the
443      * vendorName field, then set the vendorName field to null. Then it sets the businessObject of this maintainable to the
444      * VendorDetail object that contains our modification to the name fields.
445      * 
446      * @see org.kuali.rice.kns.maintenance.Maintainable#saveBusinessObject()
447      */
448     @Override
449     public void setBusinessObject(PersistableBusinessObject bo) {
450         VendorDetail originalBo = (VendorDetail) bo;
451         
452         String vendorName = originalBo.getVendorName();
453         if (originalBo.isVendorFirstLastNameIndicator() && ObjectUtils.isNotNull(vendorName)) {
454             int start = vendorName.indexOf(VendorConstants.NAME_DELIM);
455             if (start >= 0) {
456                 String lastName = vendorName.substring(0, start);
457                 String firstName = new String();
458                 if (start + VendorConstants.NAME_DELIM.length() <= vendorName.length()) {
459                     firstName = vendorName.substring(start + VendorConstants.NAME_DELIM.length(), vendorName.length());
460                 }
461 
462                 originalBo.setVendorFirstName((ObjectUtils.isNotNull(firstName) ? firstName.trim() : firstName));
463                 originalBo.setVendorLastName((ObjectUtils.isNotNull(lastName) ? lastName.trim() : lastName));
464                 originalBo.setVendorName(null);
465             }
466         }
467         
468         super.setBusinessObject(originalBo);
469     }
470 
471     /**
472      * Sets a valid detail assigned id to a vendor if the vendor has not had a detail assigned id yet. If this is a new parent whose
473      * header id is also null, this method will assign 0 as the detail assigned id. If this is a new division vendor, it will look
474      * for the count of vendor details in the database whose vendor header id match with the vendor header id of this new division,
475      * then look for the count of vendor details in the database, in a while loop, to find if a vendor detail with the same header
476      * id and detail id as the count has existed. If a vendor with such criteria exists, this method will increment the count
477      * by 1 and look up in the database again. If it does not exist, assign the count as the vendor detail id and change the
478      * boolean flag to stop the loop, because we have already found the valid detail assigned id that we were looking for
479      * 
480      * @param vendorDetail VendorDetail The vendor whose detail assigned id we're trying to assign.
481      */
482     private void setDetailAssignedId(VendorDetail vendorDetail) {
483         // If this is a new parent, let's set the detail id to 0.
484         if (ObjectUtils.isNull(vendorDetail.getVendorHeaderGeneratedIdentifier())) {
485             vendorDetail.setVendorDetailAssignedIdentifier(new Integer(0));
486         }
487         else {
488             // Try to get the count of all the vendor whose header id is the same as this header id.
489             Map criterias = new HashMap();
490             criterias.put(VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID, vendorDetail.getVendorHeaderGeneratedIdentifier());
491             BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class);
492             int count = boService.countMatching(VendorDetail.class, criterias);
493             boolean validId = false;
494             while (!validId) {
495                 criterias.put(VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID, count);
496                 int result = boService.countMatching(VendorDetail.class, criterias);
497                 if (result > 0) {
498                     // increment the detail id by 1
499                     count++;
500                 }
501                 else {
502                     // count is a validId, so we'll use count as our vendor detail assigned id
503                     validId = true;
504                     vendorDetail.setVendorDetailAssignedIdentifier(new Integer(count));
505                 }
506             }
507         }
508     }
509 
510     /**
511      * Returns the locking representation of the vendor. If the vendor detail id is not null, call the super class
512      * implementation of generateMaintenanceLocks which will set the locking key to be the header and detail ids. However, if the
513      * detail id is null, that means this is a new vendor (parent or division) and we should ignore locking.
514      * 
515      * @see org.kuali.rice.kns.maintenance.Maintainable#generateMaintenanceLocks()
516      */
517     @Override
518     public List<MaintenanceLock> generateMaintenanceLocks() {
519         if (ObjectUtils.isNotNull(((VendorDetail) getBusinessObject()).getVendorDetailAssignedIdentifier())) {
520             return super.generateMaintenanceLocks();
521         }
522         else {
523             return new ArrayList();
524         }
525     }
526 
527     /**
528      * Create a new division vendor if the user clicks on the "Create a new division" link. By default, the vendorParentIndicator is
529      * set to true in the constructor of VendorDetail, but if we're creating a new division, it's not a parent, so we need to set
530      * the vendorParentIndicator to false in this case.
531      * 
532      * @see org.kuali.rice.kns.maintenance.Maintainable#setupNewFromExisting()
533      */
534     @Override
535     public void setupNewFromExisting( MaintenanceDocument document, Map<String,String[]> parameters ) {
536         super.setupNewFromExisting(document, parameters);
537         
538         ((VendorDetail) super.getBusinessObject()).setVendorParentIndicator(false);
539         ((VendorDetail) super.getBusinessObject()).setActiveIndicator(true);
540 
541         List<Note> notes = new ArrayList<Note>();
542 
543         if (getBusinessObject().getObjectId() != null) {
544             NoteService noteService = KRADServiceLocator.getNoteService();
545             notes = noteService.getByRemoteObjectId(this.getBusinessObject().getObjectId());
546         }
547         
548         setVendorCreateAndUpdateNote(notes, VendorConstants.VendorCreateAndUpdateNotePrefixes.ADD);
549 
550         document.setNotes(notes);
551     }
552 
553     /**
554      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#isRelationshipRefreshable(java.lang.Class, java.lang.String)
555      */
556     @Override
557     protected boolean isRelationshipRefreshable(Class boClass, String relationshipName) {
558         if (VendorDetail.class.isAssignableFrom(boClass) && VendorConstants.VENDOR_HEADER_ATTR.equals(relationshipName)) {
559             return false;
560         }
561         return super.isRelationshipRefreshable(boClass, relationshipName);
562     }
563 
564     /**
565      * @see org.kuali.ole.sys.document.FinancialSystemMaintainable#answerSplitNodeQuestion(java.lang.String)
566      */
567     @Override
568     protected boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
569         if (nodeName.equals("RequiresApproval")) return SpringContext.getBean(VendorService.class).shouldVendorRouteForApproval(getDocumentNumber());
570         return super.answerSplitNodeQuestion(nodeName);
571     }
572 }
573