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.vnd.document.validation.impl;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase;
020    import org.kuali.kfs.sys.KFSConstants;
021    import org.kuali.kfs.sys.context.SpringContext;
022    import org.kuali.kfs.vnd.VendorConstants;
023    import org.kuali.kfs.vnd.VendorKeyConstants;
024    import org.kuali.kfs.vnd.VendorUtils;
025    import org.kuali.kfs.vnd.businessobject.VendorDetail;
026    import org.kuali.kfs.vnd.businessobject.VendorType;
027    import org.kuali.kfs.vnd.document.service.VendorService;
028    import org.kuali.rice.kns.document.Document;
029    import org.kuali.rice.kns.document.MaintenanceDocument;
030    import org.kuali.rice.kns.service.BusinessObjectService;
031    import org.kuali.rice.kns.service.DateTimeService;
032    import org.kuali.rice.kns.util.GlobalVariables;
033    import org.kuali.rice.kns.util.ObjectUtils;
034    
035    /**
036     * Business Prerules applicable to VendorDetail documents. These PreRules checks for the VendorDetail that needs to occur while
037     * still in the Struts processing. This includes setting the vendorName field using the values from vendorLastName and
038     * vendorFirstName, and could be used for many other purposes.
039     */
040    public class VendorPreRules extends MaintenancePreRulesBase {
041    
042        protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(VendorPreRules.class);
043    
044        protected VendorDetail newVendorDetail;
045        protected String personId;
046    
047        public VendorPreRules() {
048        }
049    
050        /**
051         * Returns the Universal User Id of the current logged-in user
052         * 
053         * @return String the PersonId
054         */
055    
056        public String getPersonId() {
057            if (ObjectUtils.isNull(personId)) {
058                this.personId = GlobalVariables.getUserSession().getPerson().getPrincipalId();
059            }
060            return this.personId;
061        }
062    
063        /**
064         * Sets up a convenience object and few other vendor attributes
065         * 
066         * @see org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase#doCustomPreRules(org.kuali.rice.kns.document.MaintenanceDocument)
067         */
068        @Override
069        protected boolean doCustomPreRules(MaintenanceDocument document) {
070            setupConvenienceObjects(document);
071            setVendorNamesAndIndicator(document);
072            setVendorRestriction(document);
073            if (StringUtils.isBlank(question) || (question.equals(VendorConstants.CHANGE_TO_PARENT_QUESTION_ID))) {
074                detectAndConfirmChangeToParent(document);
075            }
076            
077            //check to page review ONLY if it is a new vendor
078            if (newVendorDetail.getVendorHeaderGeneratedIdentifier() == null &&
079                    newVendorDetail.getVendorDetailAssignedIdentifier() == null) {
080                displayReview(document);
081            }
082            return true;
083        }
084    
085        /**
086         * Sets the convenience objects like newVendorDetail and oldVendorDetail, so you have short and easy handles to the new and old
087         * objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load all
088         * sub-objects from the DB by their primary keys, if available.
089         * 
090         * @param document - the maintenanceDocument being evaluated
091         */
092        protected void setupConvenienceObjects(MaintenanceDocument document) {
093            // setup newAccount convenience objects, make sure all possible sub-objects are populated
094            newVendorDetail = (VendorDetail) document.getNewMaintainableObject().getBusinessObject();
095        }
096    
097        /**
098         * Sets the vendorFirstLastNameIndicator to true if the first name and last name fields were filled in but the vendorName field
099         * is blank and it sets the vendorFirstLastNameIndicator to false if the vendorName field is filled in and the first name and
100         * last name fields were both blank.
101         * 
102         * @param document - the maintenanceDocument being evaluated
103         */
104        protected void setVendorNamesAndIndicator(MaintenanceDocument document) {
105            if (StringUtils.isBlank(newVendorDetail.getVendorName()) && !StringUtils.isBlank(newVendorDetail.getVendorFirstName()) && !StringUtils.isBlank(newVendorDetail.getVendorLastName())) {
106    
107                newVendorDetail.setVendorFirstLastNameIndicator(true);
108                newVendorDetail.setVendorFirstName(removeDelimiter(newVendorDetail.getVendorFirstName()));
109                newVendorDetail.setVendorLastName(removeDelimiter(newVendorDetail.getVendorLastName()));
110    
111            }
112            else if (!StringUtils.isBlank(newVendorDetail.getVendorName()) && StringUtils.isBlank(newVendorDetail.getVendorFirstName()) && StringUtils.isBlank(newVendorDetail.getVendorLastName())) {
113                newVendorDetail.setVendorFirstLastNameIndicator(false);
114            }
115        }
116    
117        /**
118         * Sets the vendorRestrictedDate and vendorRestrictedPersonIdentifier if the vendor restriction has changed from No to Yes.
119         * 
120         * @param document - the maintenanceDocument being evaluated
121         */
122        protected void setVendorRestriction(MaintenanceDocument document) {
123            VendorDetail oldVendorDetail = (VendorDetail) document.getOldMaintainableObject().getBusinessObject();
124            Boolean oldVendorRestrictedIndicator = null;
125            if (ObjectUtils.isNotNull(oldVendorDetail)) {
126                oldVendorRestrictedIndicator = oldVendorDetail.getVendorRestrictedIndicator();
127            }
128            // If the Vendor Restricted Indicator will change, change the date and person id appropriately.
129            if ((ObjectUtils.isNull(oldVendorRestrictedIndicator) || (!oldVendorRestrictedIndicator)) && ObjectUtils.isNotNull(newVendorDetail.getVendorRestrictedIndicator()) && newVendorDetail.getVendorRestrictedIndicator()) {
130                // Indicator changed from (null or false) to true.
131                newVendorDetail.setVendorRestrictedDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate());
132                newVendorDetail.setVendorRestrictedPersonIdentifier(getPersonId());
133            }
134            else if (ObjectUtils.isNotNull(oldVendorRestrictedIndicator) && oldVendorRestrictedIndicator && ObjectUtils.isNotNull(newVendorDetail.getVendorRestrictedIndicator()) && (!newVendorDetail.getVendorRestrictedIndicator())) {
135                // Indicator changed from true to false.
136                newVendorDetail.setVendorRestrictedDate(null);
137                newVendorDetail.setVendorRestrictedPersonIdentifier(null);
138            }
139    
140        }
141    
142        /**
143         * This is a helper method to remove all the delimiters from the vendor name
144         * 
145         * @param str the original vendorName
146         * @return result String the vendorName after the delimiters have been removed
147         */
148        protected String removeDelimiter(String str) {
149            String result = str.replaceAll(VendorConstants.NAME_DELIM, KFSConstants.BLANK_SPACE);
150            return result;
151        }
152    
153    
154        /**
155         * Displays a review if indicated by the vendor type and the associated text from that type
156         * 
157         * @param document - vendordetail document
158         */
159        public void displayReview(Document document) {
160            VendorDetail vendorDetail = (VendorDetail) document.getDocumentBusinessObject();
161    
162            VendorType vendorType = vendorDetail.getVendorHeader().getVendorType();
163    
164            if (vendorType == null) {
165                vendorType = new VendorType();
166                vendorType.setVendorTypeCode(vendorDetail.getVendorHeader().getVendorTypeCode());
167                vendorType = (VendorType) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorType);
168            }
169            if (vendorType != null && vendorType.isVendorShowReviewIndicator()) {
170                String questionText = vendorType.getVendorReviewText();
171    
172                //
173                // Only recognize the review request if the question text isn't null.
174                // Why preview something that doesn't exist?
175                //
176                if (questionText != null) {
177    
178                    if (vendorDetail.getVendorName() != null) {
179                        questionText = questionText.replace("{0}", vendorDetail.getVendorName());
180                    }
181                    else {
182                        questionText = questionText.replace("{0}", "(not entered)");
183                    }
184                    questionText = questionText.replace("{1}", document.getDocumentNumber());
185                    Boolean proceed = super.askOrAnalyzeYesNoQuestion(VendorConstants.ACKNOWLEDGE_NEW_VENDOR_INFO, questionText);
186    
187                    if (!proceed) {
188                        abortRulesCheck();
189                    }
190                }
191            }
192        }
193        
194       /**
195         * This method displays a review if indicated by the vendor type and the associated text from that type This method screens the
196         * current document for changes from division vendor to parent vendor. If the document does contain such a change, the question
197         * framework is invoked to obtain the user's confirmation for the change. If confirmation is obtained, a note is added to the
198         * old parent vendor. Indicators are set appropriately.
199         * 
200         * @param document The vendor-change-containing MaintenanceDocument under examination
201         */
202        protected void detectAndConfirmChangeToParent(MaintenanceDocument document) {
203            boolean proceed = true;
204            VendorDetail oldVendorDetail = (VendorDetail) document.getOldMaintainableObject().getBusinessObject();
205            boolean oldVendorIsParent = oldVendorDetail.isVendorParentIndicator();
206            boolean newVendorIsParent = newVendorDetail.isVendorParentIndicator();
207            if (!oldVendorIsParent && newVendorIsParent) {
208                // A change to division is being tried. Obtain confirmation.
209                VendorDetail oldParentVendor = SpringContext.getBean(VendorService.class).getParentVendor(oldVendorDetail.getVendorHeaderGeneratedIdentifier());
210                String oldParentVendorName = oldParentVendor.getVendorName();
211                String oldParentVendorNumber = oldParentVendor.getVendorNumber();
212                proceed = askOrAnalyzeYesNoQuestion(VendorConstants.CHANGE_TO_PARENT_QUESTION_ID, VendorUtils.buildMessageText(VendorKeyConstants.CONFIRM_VENDOR_CHANGE_TO_PARENT, oldVendorDetail.getVendorName() + "  (" + oldVendorDetail.getVendorNumber() + ")", oldParentVendorName + " (" + oldParentVendorNumber + ")"));
213                if (proceed) {
214                    newVendorDetail.setVendorParentIndicator(true);
215                }
216                else {
217                    newVendorDetail.setVendorParentIndicator(false);
218                }
219            }
220            if (!proceed) {
221                abortRulesCheck();
222            }
223        }
224    
225    }
226