/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.vnd.document.validation.impl;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.vnd.VendorConstants;
import org.kuali.kfs.vnd.VendorKeyConstants;
import org.kuali.kfs.vnd.VendorUtils;
import org.kuali.kfs.vnd.businessobject.VendorDetail;
import org.kuali.kfs.vnd.businessobject.VendorType;
import org.kuali.kfs.vnd.document.service.VendorService;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.kns.document.MaintenanceDocument;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.ObjectUtils;
/**
* Business Prerules applicable to VendorDetail documents. These PreRules checks for the VendorDetail that needs to occur while
* still in the Struts processing. This includes setting the vendorName field using the values from vendorLastName and
* vendorFirstName, and could be used for many other purposes.
*/
public class VendorPreRules extends MaintenancePreRulesBase {
protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(VendorPreRules.class);
protected VendorDetail newVendorDetail;
protected String personId;
public VendorPreRules() {
}
/**
* Returns the Universal User Id of the current logged-in user
*
* @return String the PersonId
*/
public String getPersonId() {
if (ObjectUtils.isNull(personId)) {
this.personId = GlobalVariables.getUserSession().getPerson().getPrincipalId();
}
return this.personId;
}
/**
* Sets up a convenience object and few other vendor attributes
*
* @see org.kuali.kfs.coa.document.validation.impl.MaintenancePreRulesBase#doCustomPreRules(org.kuali.rice.kns.document.MaintenanceDocument)
*/
@Override
protected boolean doCustomPreRules(MaintenanceDocument document) {
setupConvenienceObjects(document);
setVendorNamesAndIndicator(document);
setVendorRestriction(document);
if (StringUtils.isBlank(question) || (question.equals(VendorConstants.CHANGE_TO_PARENT_QUESTION_ID))) {
detectAndConfirmChangeToParent(document);
}
//check to page review ONLY if it is a new vendor
if (newVendorDetail.getVendorHeaderGeneratedIdentifier() == null &&
newVendorDetail.getVendorDetailAssignedIdentifier() == null) {
displayReview(document);
}
return true;
}
/**
* Sets the convenience objects like newVendorDetail and oldVendorDetail, so you have short and easy handles to the new and old
* objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load all
* sub-objects from the DB by their primary keys, if available.
*
* @param document - the maintenanceDocument being evaluated
*/
protected void setupConvenienceObjects(MaintenanceDocument document) {
// setup newAccount convenience objects, make sure all possible sub-objects are populated
newVendorDetail = (VendorDetail) document.getNewMaintainableObject().getBusinessObject();
}
/**
* Sets the vendorFirstLastNameIndicator to true if the first name and last name fields were filled in but the vendorName field
* is blank and it sets the vendorFirstLastNameIndicator to false if the vendorName field is filled in and the first name and
* last name fields were both blank.
*
* @param document - the maintenanceDocument being evaluated
*/
protected void setVendorNamesAndIndicator(MaintenanceDocument document) {
if (StringUtils.isBlank(newVendorDetail.getVendorName()) && !StringUtils.isBlank(newVendorDetail.getVendorFirstName()) && !StringUtils.isBlank(newVendorDetail.getVendorLastName())) {
newVendorDetail.setVendorFirstLastNameIndicator(true);
newVendorDetail.setVendorFirstName(removeDelimiter(newVendorDetail.getVendorFirstName()));
newVendorDetail.setVendorLastName(removeDelimiter(newVendorDetail.getVendorLastName()));
}
else if (!StringUtils.isBlank(newVendorDetail.getVendorName()) && StringUtils.isBlank(newVendorDetail.getVendorFirstName()) && StringUtils.isBlank(newVendorDetail.getVendorLastName())) {
newVendorDetail.setVendorFirstLastNameIndicator(false);
}
}
/**
* Sets the vendorRestrictedDate and vendorRestrictedPersonIdentifier if the vendor restriction has changed from No to Yes.
*
* @param document - the maintenanceDocument being evaluated
*/
protected void setVendorRestriction(MaintenanceDocument document) {
VendorDetail oldVendorDetail = (VendorDetail) document.getOldMaintainableObject().getBusinessObject();
Boolean oldVendorRestrictedIndicator = null;
if (ObjectUtils.isNotNull(oldVendorDetail)) {
oldVendorRestrictedIndicator = oldVendorDetail.getVendorRestrictedIndicator();
}
// If the Vendor Restricted Indicator will change, change the date and person id appropriately.
if ((ObjectUtils.isNull(oldVendorRestrictedIndicator) || (!oldVendorRestrictedIndicator)) && ObjectUtils.isNotNull(newVendorDetail.getVendorRestrictedIndicator()) && newVendorDetail.getVendorRestrictedIndicator()) {
// Indicator changed from (null or false) to true.
if(newVendorDetail.getVendorRestrictedDate() == null){
newVendorDetail.setVendorRestrictedDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate());
}
if(newVendorDetail.getVendorRestrictedPersonIdentifier() == null) {
newVendorDetail.setVendorRestrictedPersonIdentifier(getPersonId());
}
}
else if (ObjectUtils.isNotNull(oldVendorRestrictedIndicator) && oldVendorRestrictedIndicator && ObjectUtils.isNotNull(newVendorDetail.getVendorRestrictedIndicator()) && (!newVendorDetail.getVendorRestrictedIndicator())) {
// Indicator changed from true to false.
newVendorDetail.setVendorRestrictedDate(null);
newVendorDetail.setVendorRestrictedPersonIdentifier(null);
}
}
/**
* This is a helper method to remove all the delimiters from the vendor name
*
* @param str the original vendorName
* @return result String the vendorName after the delimiters have been removed
*/
protected String removeDelimiter(String str) {
String result = str.replaceAll(VendorConstants.NAME_DELIM, KFSConstants.BLANK_SPACE);
return result;
}
/**
* Displays a review if indicated by the vendor type and the associated text from that type
*
* @param document - vendordetail document
*/
public void displayReview(MaintenanceDocument document) {
VendorDetail vendorDetail = (VendorDetail) document.getDocumentBusinessObject();
VendorType vendorType = vendorDetail.getVendorHeader().getVendorType();
if (vendorType == null) {
vendorType = new VendorType();
vendorType.setVendorTypeCode(vendorDetail.getVendorHeader().getVendorTypeCode());
vendorType = (VendorType) SpringContext.getBean(BusinessObjectService.class).retrieve(vendorType);
}
if (vendorType != null && vendorType.isVendorShowReviewIndicator()) {
String questionText = vendorType.getVendorReviewText();
//
// Only recognize the review request if the question text isn't null.
// Why preview something that doesn't exist?
//
if (questionText != null) {
if (vendorDetail.getVendorName() != null) {
questionText = questionText.replace("{0}", vendorDetail.getVendorName());
}
else {
questionText = questionText.replace("{0}", "(not entered)");
}
questionText = questionText.replace("{1}", document.getDocumentNumber());
Boolean proceed = super.askOrAnalyzeYesNoQuestion(VendorConstants.ACKNOWLEDGE_NEW_VENDOR_INFO, questionText);
if (!proceed) {
abortRulesCheck();
}
}
}
}
/**
* This method displays a review if indicated by the vendor type and the associated text from that type This method screens the
* current document for changes from division vendor to parent vendor. If the document does contain such a change, the question
* framework is invoked to obtain the user's confirmation for the change. If confirmation is obtained, a note is added to the
* old parent vendor. Indicators are set appropriately.
*
* @param document The vendor-change-containing MaintenanceDocument under examination
*/
protected void detectAndConfirmChangeToParent(MaintenanceDocument document) {
boolean proceed = true;
VendorDetail oldVendorDetail = (VendorDetail) document.getOldMaintainableObject().getBusinessObject();
boolean oldVendorIsParent = oldVendorDetail.isVendorParentIndicator();
boolean newVendorIsParent = newVendorDetail.isVendorParentIndicator();
if (!oldVendorIsParent && newVendorIsParent) {
// A change to division is being tried. Obtain confirmation.
VendorDetail oldParentVendor = SpringContext.getBean(VendorService.class).getParentVendor(oldVendorDetail.getVendorHeaderGeneratedIdentifier());
String oldParentVendorName = oldParentVendor.getVendorName();
String oldParentVendorNumber = oldParentVendor.getVendorNumber();
proceed = askOrAnalyzeYesNoQuestion(VendorConstants.CHANGE_TO_PARENT_QUESTION_ID, VendorUtils.buildMessageText(VendorKeyConstants.CONFIRM_VENDOR_CHANGE_TO_PARENT, oldVendorDetail.getVendorName() + " (" + oldVendorDetail.getVendorNumber() + ")", oldParentVendorName + " (" + oldParentVendorNumber + ")"));
if (proceed) {
newVendorDetail.setVendorParentIndicator(true);
}
else {
newVendorDetail.setVendorParentIndicator(false);
}
}
if (!proceed) {
abortRulesCheck();
}
}
}