0001: /*
0002: * Copyright 2007 The Kuali Foundation.
0003: *
0004: * Licensed under the Educational Community License, Version 1.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.opensource.org/licenses/ecl1.php
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: package org.kuali.module.vendor.rules;
0017:
0018: import java.lang.reflect.Field;
0019: import java.util.ArrayList;
0020: import java.util.Collection;
0021: import java.util.Date;
0022: import java.util.HashMap;
0023: import java.util.HashSet;
0024: import java.util.Iterator;
0025: import java.util.List;
0026: import java.util.Map;
0027: import java.util.Set;
0028:
0029: import org.apache.commons.lang.StringUtils;
0030: import org.kuali.core.authorization.FieldAuthorization;
0031: import org.kuali.core.bo.PersistableBusinessObject;
0032: import org.kuali.core.bo.PersistableBusinessObjectBase;
0033: import org.kuali.core.bo.user.UniversalUser;
0034: import org.kuali.core.document.MaintenanceDocument;
0035: import org.kuali.core.document.authorization.MaintenanceDocumentAuthorizations;
0036: import org.kuali.core.document.authorization.MaintenanceDocumentAuthorizer;
0037: import org.kuali.core.exceptions.UnknownDocumentIdException;
0038: import org.kuali.core.maintenance.Maintainable;
0039: import org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase;
0040: import org.kuali.core.service.BusinessObjectService;
0041: import org.kuali.core.service.DateTimeService;
0042: import org.kuali.core.service.DocumentService;
0043: import org.kuali.core.service.PersistenceService;
0044: import org.kuali.core.util.GlobalVariables;
0045: import org.kuali.core.util.KualiDecimal;
0046: import org.kuali.core.util.ObjectUtils;
0047: import org.kuali.core.workflow.service.KualiWorkflowDocument;
0048: import org.kuali.kfs.KFSConstants;
0049: import org.kuali.kfs.KFSKeyConstants;
0050: import org.kuali.kfs.KFSPropertyConstants;
0051: import org.kuali.kfs.bo.Country;
0052: import org.kuali.kfs.context.SpringContext;
0053: import org.kuali.kfs.service.ParameterService;
0054: import org.kuali.module.chart.bo.Chart;
0055: import org.kuali.module.chart.bo.Org;
0056: import org.kuali.module.vendor.VendorConstants;
0057: import org.kuali.module.vendor.VendorKeyConstants;
0058: import org.kuali.module.vendor.VendorParameterConstants;
0059: import org.kuali.module.vendor.VendorPropertyConstants;
0060: import org.kuali.module.vendor.bo.AddressType;
0061: import org.kuali.module.vendor.bo.OwnershipType;
0062: import org.kuali.module.vendor.bo.VendorAddress;
0063: import org.kuali.module.vendor.bo.VendorContact;
0064: import org.kuali.module.vendor.bo.VendorContract;
0065: import org.kuali.module.vendor.bo.VendorContractOrganization;
0066: import org.kuali.module.vendor.bo.VendorCustomerNumber;
0067: import org.kuali.module.vendor.bo.VendorDefaultAddress;
0068: import org.kuali.module.vendor.bo.VendorDetail;
0069: import org.kuali.module.vendor.service.PhoneNumberService;
0070: import org.kuali.module.vendor.service.TaxNumberService;
0071:
0072: import edu.iu.uis.eden.exception.WorkflowException;
0073:
0074: /**
0075: * Business rules applicable to VendorDetail document.
0076: */
0077: public class VendorRule extends MaintenanceDocumentRuleBase {
0078:
0079: private VendorDetail oldVendor;
0080: private VendorDetail newVendor;
0081: private static KualiDecimal VENDOR_MIN_ORDER_AMOUNT;
0082:
0083: /**
0084: * Overrides the setupBaseConvenienceObjects from the superclass because we cannot use the setupBaseConvenienceObjects from the
0085: * superclass. The reason we cannot use the superclass method is because it calls the updateNonUpdateableReferences for
0086: * everything and we cannot do that for parent vendors, because we want to update vendor header information only on parent
0087: * vendors, so the saving of the vendor header is done manually. If we call the updateNonUpdateableReferences, it is going to
0088: * overwrite any changes that the user might have done in the vendor header with the existing values in the database.
0089: *
0090: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#setupBaseConvenienceObjects(org.kuali.core.document.MaintenanceDocument)
0091: */
0092: @Override
0093: public void setupBaseConvenienceObjects(MaintenanceDocument document) {
0094: oldVendor = (VendorDetail) document.getOldMaintainableObject()
0095: .getBusinessObject();
0096: newVendor = (VendorDetail) document.getNewMaintainableObject()
0097: .getBusinessObject();
0098: super .setNewBo(newVendor);
0099: setupConvenienceObjects();
0100: }
0101:
0102: /**
0103: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects()
0104: */
0105: @Override
0106: public void setupConvenienceObjects() {
0107:
0108: // setup oldVendor convenience objects, make sure all possible sub-objects are populated
0109: refreshSubObjects(oldVendor);
0110:
0111: // setup newVendor convenience objects, make sure all possible sub-objects are populated
0112: refreshSubObjects(newVendor);
0113:
0114: }
0115:
0116: /**
0117: * Overrides the checkAuthorizationRestrictions in MaintenanceDocumentRuleBase. The reason we needed to override it is because
0118: * in vendor, we had to save the fields in the vendor header separately than vendor detail, and those fields are only editable
0119: * when the vendor is a parent. Therefore we had to override the setupBaseConvenienceObjects method, which then causes us unable
0120: * to set the oldBo of the super class because the oldBo is not accessible from outside the class. This will cause the
0121: * checkAuthorizationRestrictions of the superclass to fail while processing division vendors that contain those restricted
0122: * (uneditable) fields, because the oldBo is null and will throw the null pointer exception. Therefore we're overriding the
0123: * checkAuthorizationRestrictions in here and we'll use the oldVendor instead of oldBo of the superclass while comparing the old
0124: * and new values. This also does not enforce the authorization restrictions if the restricted fields are the fields in vendor
0125: * header or the vendor is not a parent vendor, because in this case, the fields are uneditable from the user interface.
0126: *
0127: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#checkAuthorizationRestrictions(org.kuali.core.document.MaintenanceDocument)
0128: */
0129: @Override
0130: protected boolean checkAuthorizationRestrictions(
0131: MaintenanceDocument document) {
0132:
0133: boolean success = true;
0134: boolean changed = false;
0135:
0136: boolean isInitiator = false;
0137: boolean isApprover = false;
0138:
0139: Object oldValue = null;
0140: Object newValue = null;
0141: Object savedValue = null;
0142:
0143: KualiWorkflowDocument workflowDocument = null;
0144: UniversalUser user = GlobalVariables.getUserSession()
0145: .getUniversalUser();
0146: try {
0147: workflowDocument = getWorkflowDocumentService()
0148: .createWorkflowDocument(
0149: Long.valueOf(document.getDocumentNumber()),
0150: user);
0151: } catch (WorkflowException e) {
0152: throw new UnknownDocumentIdException(
0153: "no document found for documentHeaderId '"
0154: + document.getDocumentNumber() + "'", e);
0155: }
0156: if (user.getPersonUserIdentifier().equalsIgnoreCase(
0157: workflowDocument.getInitiatorNetworkId())) {
0158: // if these are the same person then we know it is the initiator
0159: isInitiator = true;
0160: } else if (workflowDocument.isApprovalRequested()) {
0161: isApprover = true;
0162: }
0163:
0164: // get the correct documentAuthorizer for this document
0165: MaintenanceDocumentAuthorizer documentAuthorizer = (MaintenanceDocumentAuthorizer) documentAuthorizationService
0166: .getDocumentAuthorizer(document);
0167:
0168: // get a new instance of MaintenanceDocumentAuthorizations for this context
0169: MaintenanceDocumentAuthorizations auths = documentAuthorizer
0170: .getFieldAuthorizations(document, user);
0171:
0172: // load a temp copy of the document from the DB to compare to for changes
0173: MaintenanceDocument savedDoc = null;
0174: Maintainable savedNewMaintainable = null;
0175: PersistableBusinessObject savedNewBo = null;
0176:
0177: if (isApprover) {
0178: try {
0179: DocumentService docService = SpringContext
0180: .getBean(DocumentService.class);
0181: savedDoc = (MaintenanceDocument) docService
0182: .getByDocumentHeaderId(document
0183: .getDocumentNumber());
0184: } catch (WorkflowException e) {
0185: throw new RuntimeException(
0186: "A WorkflowException was thrown which prevented the loading of "
0187: + "the comparison document ("
0188: + document.getDocumentNumber() + ")", e);
0189: }
0190:
0191: // attempt to retrieve the BO, but leave it blank if it or any of the objects on the path
0192: // to it are blank
0193: if (savedDoc != null) {
0194: savedNewMaintainable = savedDoc
0195: .getNewMaintainableObject();
0196: if (savedNewMaintainable != null) {
0197: savedNewBo = savedNewMaintainable
0198: .getBusinessObject();
0199: }
0200: }
0201: }
0202:
0203: // setup in-loop members
0204: FieldAuthorization fieldAuthorization = null;
0205:
0206: // walk through all the restrictions
0207: Collection restrictedFields = auths.getAuthFieldNames();
0208: for (Iterator iter = restrictedFields.iterator(); iter
0209: .hasNext();) {
0210: String fieldName = (String) iter.next();
0211:
0212: if (fieldName
0213: .indexOf(VendorPropertyConstants.VENDOR_HEADER_PREFIX) < 0
0214: || newVendor.isVendorParentIndicator()) {
0215: // get the specific field authorization structure
0216: fieldAuthorization = auths
0217: .getAuthFieldAuthorization(fieldName);
0218:
0219: // if there are any restrictions, then enforce them
0220: if (fieldAuthorization.isRestricted()) {
0221: // reset the changed flag
0222: changed = false;
0223:
0224: // new value should always be the same regardles of who is
0225: // making the request
0226: newValue = ObjectUtils.getNestedValue(newVendor,
0227: fieldName);
0228:
0229: // first we need to handle the case of edit doc && initiator
0230: if (isInitiator && document.isEdit()) {
0231: // old value must equal new value
0232: oldValue = ObjectUtils.getNestedValue(
0233: oldVendor, fieldName);
0234: } else if (isApprover && savedNewBo != null) {
0235: oldValue = ObjectUtils.getNestedValue(
0236: savedNewBo, fieldName);
0237: }
0238:
0239: // check to make sure nothing has changed
0240: if (oldValue == null && newValue == null) {
0241: changed = false;
0242: } else if ((oldValue == null && newValue != null)
0243: || (oldValue != null && newValue == null)) {
0244: changed = true;
0245: } else if (oldValue != null && newValue != null) {
0246: if (!oldValue.equals(newValue)) {
0247: changed = true;
0248: }
0249: }
0250:
0251: // if changed and a NEW doc, but the new value is the default value, then let it go
0252: // we dont allow changing to default values for EDIT docs though, only NEW
0253: if (changed && document.isNew()) {
0254: String defaultValue = maintDocDictionaryService
0255: .getFieldDefaultValue(document
0256: .getNewMaintainableObject()
0257: .getBoClass(), fieldName);
0258:
0259: // get the string value of newValue
0260: String newStringValue = newValue.toString();
0261: // if the newValue is the default value, then ignore
0262: if (newStringValue
0263: .equalsIgnoreCase(defaultValue)) {
0264: changed = false;
0265: }
0266: }
0267:
0268: // if anything has changed, complain
0269: if (changed) {
0270: String humanReadableFieldName = ddService
0271: .getAttributeLabel(document
0272: .getNewMaintainableObject()
0273: .getBoClass(), fieldName);
0274: putFieldError(
0275: fieldName,
0276: KFSKeyConstants.ERROR_DOCUMENT_AUTHORIZATION_RESTRICTED_FIELD_CHANGED,
0277: humanReadableFieldName);
0278: success &= false;
0279: }
0280: }
0281: }
0282: }
0283: return success;
0284: }
0285:
0286: /**
0287: * Refreshes the references of vendor detail and its sub objects
0288: *
0289: * @param vendor VendorDetail document
0290: */
0291: void refreshSubObjects(VendorDetail vendor) {
0292: if (vendor == null) {
0293: return;
0294: }
0295:
0296: // If this is a division vendor, we need to do a refreshNonUpdateableReferences
0297: // and also refreshes the vendor header, since the user aren't supposed to
0298: // make any updates of vendor header's attributes while editing a division vendor
0299: if (!vendor.isVendorParentIndicator()) {
0300: vendor.refreshNonUpdateableReferences();
0301: vendor.getVendorHeader().refreshNonUpdateableReferences();
0302:
0303: } else {
0304: // Retrieve the references objects of the vendor header of this vendor.
0305: List<String> headerFieldNames = getObjectReferencesListFromBOClass(vendor
0306: .getVendorHeader().getClass());
0307: SpringContext.getBean(PersistenceService.class)
0308: .retrieveReferenceObjects(vendor.getVendorHeader(),
0309: headerFieldNames);
0310:
0311: // We still need to retrieve all the other references of this vendor in addition to
0312: // vendor header. Since this is a parent vendor, whose vendor header saving is handled manually,
0313: // we have already retrieved references for vendor header's attributes above, so we should
0314: // exclude retrieving reference objects of vendor header.
0315: List<String> detailFieldNames = getObjectReferencesListFromBOClass(vendor
0316: .getClass());
0317: detailFieldNames.remove(VendorConstants.VENDOR_HEADER_ATTR);
0318: SpringContext.getBean(PersistenceService.class)
0319: .retrieveReferenceObjects(vendor, detailFieldNames);
0320: }
0321:
0322: // refresh addresses
0323: if (vendor.getVendorAddresses() != null) {
0324: for (VendorAddress address : vendor.getVendorAddresses()) {
0325: address.refreshNonUpdateableReferences();
0326: if (address.getVendorDefaultAddresses() != null) {
0327: for (VendorDefaultAddress defaultAddress : address
0328: .getVendorDefaultAddresses()) {
0329: defaultAddress.refreshNonUpdateableReferences();
0330: }
0331: }
0332: }
0333: }
0334: // refresh contacts
0335: if (vendor.getVendorContacts() != null) {
0336: for (VendorContact contact : vendor.getVendorContacts()) {
0337: contact.refreshNonUpdateableReferences();
0338: }
0339: }
0340: // refresh contracts
0341: if (vendor.getVendorContracts() != null) {
0342: for (VendorContract contract : vendor.getVendorContracts()) {
0343: contract.refreshNonUpdateableReferences();
0344: }
0345: }
0346: }
0347:
0348: /**
0349: * This is currently used as a helper to get a list of object references (e.g. vendorType, vendorOwnershipType, etc) from a
0350: * BusinessObject (e.g. VendorHeader, VendorDetail, etc) class dynamically. Feel free to enhance it, refactor it or move it to a
0351: * superclass or elsewhere as you see appropriate.
0352: *
0353: * @param theClass The Class name of the object whose objects references list are extracted
0354: * @return List a List of attributes of the class
0355: */
0356: private List getObjectReferencesListFromBOClass(Class theClass) {
0357: List<String> results = new ArrayList();
0358: for (Field theField : theClass.getDeclaredFields()) {
0359: try {
0360: theField.getType().asSubclass(
0361: PersistableBusinessObjectBase.class);
0362: // only add the field to the result list if this is not
0363: // a UniversalUser
0364: if (!theField.getType().equals(UniversalUser.class)) {
0365: results.add(theField.getName());
0366: }
0367: } catch (ClassCastException e) {
0368: // If we catches this, it means the "theField" can't be casted as a BusinessObjectBase,
0369: // so we won't add it to the results list because this method is aiming at getting
0370: // a list of object references that are subclasses of BusinessObjectBase.
0371: }
0372: }
0373: return results;
0374: }
0375:
0376: /**
0377: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
0378: */
0379: @Override
0380: protected boolean processCustomApproveDocumentBusinessRules(
0381: MaintenanceDocument document) {
0382: boolean valid = processValidation(document);
0383: return valid
0384: & super
0385: .processCustomApproveDocumentBusinessRules(document);
0386: }
0387:
0388: /**
0389: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
0390: */
0391: @Override
0392: protected boolean processCustomRouteDocumentBusinessRules(
0393: MaintenanceDocument document) {
0394: boolean valid = processValidation(document);
0395: return valid
0396: & super
0397: .processCustomRouteDocumentBusinessRules(document);
0398: }
0399:
0400: /**
0401: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
0402: */
0403: @Override
0404: protected boolean processCustomSaveDocumentBusinessRules(
0405: MaintenanceDocument document) {
0406: boolean valid = true;
0407: return valid
0408: & super
0409: .processCustomSaveDocumentBusinessRules(document);
0410: }
0411:
0412: /**
0413: * Validates VendorDetail and its VendorContracts.
0414: *
0415: * @param document MaintenanceDocument instance
0416: * @return boolean false or true
0417: */
0418: private boolean processValidation(MaintenanceDocument document) {
0419: boolean valid = true;
0420:
0421: valid &= processVendorValidation(document);
0422: if (ObjectUtils.isNotNull(newVendor.getVendorHeader()
0423: .getVendorType())) {
0424: valid &= processAddressValidation(document);
0425: }
0426: valid &= processContractValidation(document);
0427:
0428: return valid;
0429: }
0430:
0431: /**
0432: * Validates VendorDetail document.
0433: *
0434: * @param document MaintenanceDocument instance
0435: * @return boolean false or true
0436: */
0437: boolean processVendorValidation(MaintenanceDocument document) {
0438: boolean valid = true;
0439: VendorDetail vendorDetail = (VendorDetail) document
0440: .getNewMaintainableObject().getBusinessObject();
0441:
0442: valid &= validateTaxTypeAndTaxNumberBlankness(vendorDetail);
0443: valid &= validateParentVendorTaxNumber(vendorDetail);
0444: valid &= validateOwnershipTypeAllowed(vendorDetail);
0445: valid &= validateTaxNumberFromTaxNumberService(vendorDetail);
0446: valid &= validateRestrictedReasonRequiredness(vendorDetail);
0447: valid &= validateInactiveReasonRequiredness(vendorDetail);
0448:
0449: if (ObjectUtils.isNotNull(vendorDetail.getVendorHeader()
0450: .getVendorType())) {
0451: valid &= validateTaxNumberRequiredness(vendorDetail);
0452: }
0453:
0454: valid &= validateVendorNames(vendorDetail);
0455: valid &= validateMinimumOrderAmount(vendorDetail);
0456: valid &= validateOwnershipCategory(vendorDetail);
0457: valid &= validateVendorWithholdingTaxDates(vendorDetail);
0458: valid &= validateVendorW8BenOrW9ReceivedIndicator(vendorDetail);
0459: return valid;
0460: }
0461:
0462: /**
0463: * Validates that if the vendor is set to be inactive, the inactive reason is required.
0464: *
0465: * @param vendorDetail the VendorDetail object to be validated
0466: * @return boolean false if the vendor is inactive and the inactive reason is empty
0467: */
0468: boolean validateInactiveReasonRequiredness(VendorDetail vendorDetail) {
0469: if (!vendorDetail.isActiveIndicator()
0470: && StringUtils.isEmpty(vendorDetail
0471: .getVendorInactiveReasonCode())) {
0472: putFieldError(
0473: VendorPropertyConstants.VENDOR_INACTIVE_REASON,
0474: VendorKeyConstants.ERROR_INACTIVE_REASON_REQUIRED);
0475: return false;
0476: }
0477: return true;
0478: }
0479:
0480: /**
0481: * Validates that if the vendor is not foreign and if the vendor type's tax number required indicator is true, then the tax
0482: * number is required. If the vendor foreign indicator is true, then the tax number is not required regardless of its vendor
0483: * type.
0484: *
0485: * @param vendorDetail the VendorDetail object to be validated
0486: * @return boolean false if there is no tax number and the indicator is true.
0487: */
0488: boolean validateTaxNumberRequiredness(VendorDetail vendorDetail) {
0489: if (!vendorDetail.getVendorHeader().getVendorForeignIndicator()
0490: && vendorDetail.getVendorHeader().getVendorType()
0491: .isVendorTaxNumberRequiredIndicator()
0492: && StringUtils.isBlank(vendorDetail.getVendorHeader()
0493: .getVendorTaxNumber())) {
0494: if (vendorDetail.isVendorParentIndicator()) {
0495: putFieldError(
0496: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0497: VendorKeyConstants.ERROR_VENDOR_TYPE_REQUIRES_TAX_NUMBER,
0498: vendorDetail.getVendorHeader().getVendorType()
0499: .getVendorTypeDescription());
0500: } else {
0501: putFieldError(
0502: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0503: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0504: }
0505: return false;
0506: }
0507: return true;
0508: }
0509:
0510: /**
0511: * Validates that, if the vendor is set to be restricted, the restricted reason is required.
0512: *
0513: * @param vendorDetail The VendorDetail object to be validated
0514: * @return boolean false if the vendor is restricted and the restricted reason is empty
0515: */
0516: boolean validateRestrictedReasonRequiredness(
0517: VendorDetail vendorDetail) {
0518: if (ObjectUtils.isNotNull(vendorDetail
0519: .getVendorRestrictedIndicator())
0520: && vendorDetail.getVendorRestrictedIndicator()
0521: && StringUtils.isEmpty(vendorDetail
0522: .getVendorRestrictedReasonText())) {
0523: putFieldError(
0524: VendorPropertyConstants.VENDOR_RESTRICTED_REASON_TEXT,
0525: VendorKeyConstants.ERROR_RESTRICTED_REASON_REQUIRED);
0526: return false;
0527: }
0528: return true;
0529: }
0530:
0531: /**
0532: * Validates that if vendor is parent, then tax # and tax type combo should be unique by checking for the existence of vendor(s)
0533: * with the same tax # and tax type in the existing vendor header table. Ideally we're also supposed to check for pending
0534: * vendors, but at the moment, the pending vendors are under research investigation, so we're only checking the existing vendors
0535: * for now. If the vendor is a parent and the validation fails, display the actual error message. If the vendor is not a parent
0536: * and the validation fails, display the error message that the parent of this vendor needs to be changed, please contact
0537: * Purchasing Dept. While checking for the existence of vendors with the same tax # and tax type, exclude the vendors with the
0538: * same id. KULPURAP-302: Allow a duplication of a tax number in vendor header if there are only "inactive" header records with
0539: * the duplicate record
0540: *
0541: * @param vendorDetail the VendorDetail object to be validated
0542: * @return boolean true if the vendorDetail passes the unique tax # and tax type validation.
0543: */
0544: boolean validateParentVendorTaxNumber(VendorDetail vendorDetail) {
0545: boolean valid = true;
0546: boolean isParent = vendorDetail.isVendorParentIndicator();
0547: Map criteria = new HashMap();
0548: criteria.put(VendorPropertyConstants.VENDOR_TAX_TYPE_CODE,
0549: vendorDetail.getVendorHeader().getVendorTaxTypeCode());
0550: criteria.put(VendorPropertyConstants.VENDOR_TAX_NUMBER,
0551: vendorDetail.getVendorHeader().getVendorTaxNumber());
0552: criteria.put(KFSPropertyConstants.ACTIVE_INDICATOR, true);
0553: Map negativeCriteria = new HashMap();
0554: int existingVendor = 0;
0555: // If this is editing an existing vendor, we have to include the current vendor's
0556: // header generated id in the negative criteria so that the current vendor is
0557: // excluded from the search
0558: if (ObjectUtils.isNotNull(vendorDetail
0559: .getVendorHeaderGeneratedIdentifier())) {
0560: negativeCriteria.put(
0561: VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID,
0562: vendorDetail.getVendorHeaderGeneratedIdentifier());
0563: existingVendor = getBoService().countMatching(
0564: VendorDetail.class, criteria, negativeCriteria);
0565: } else {
0566: // If this is creating a new vendor, we can't include the header generated id
0567: // in the negative criteria because it's null, so we'll only look for existing
0568: // vendors with the same tax # and tax type regardless of the vendor header generated id.
0569: existingVendor = getBoService().countMatching(
0570: VendorDetail.class, criteria);
0571: }
0572: if (existingVendor > 0) {
0573: if (isParent) {
0574: putFieldError(
0575: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0576: VendorKeyConstants.ERROR_VENDOR_TAX_TYPE_AND_NUMBER_COMBO_EXISTS);
0577: } else {
0578: putFieldError(
0579: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0580: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0581: }
0582: valid &= false;
0583: }
0584: return valid;
0585: }
0586:
0587: /**
0588: * Validates that the following business rules are satisfied: 1. Tax type cannot be blank if the tax # is not blank. 2. Tax type
0589: * cannot be set if the tax # is blank. If the vendor is a parent and the validation fails, we'll display an error message
0590: * indicating that the tax type cannot be blank if the tax # is not blank or that the tax type cannot be set if the tax # is
0591: * blank. If the vendor is not a parent and the validation fails, we'll display an error message indicating that the parent of
0592: * this vendor needs to be changed, please contact Purchasing Dept.
0593: *
0594: * @param vendorDetail the VendorDetail object to be validated
0595: * @return boolean true if the vendor Detail passes the validation and false otherwise.
0596: */
0597: boolean validateTaxTypeAndTaxNumberBlankness(
0598: VendorDetail vendorDetail) {
0599: boolean valid = true;
0600: boolean isParent = vendorDetail.isVendorParentIndicator();
0601: if (!StringUtils.isBlank(vendorDetail.getVendorHeader()
0602: .getVendorTaxNumber())
0603: && (StringUtils.isBlank(vendorDetail.getVendorHeader()
0604: .getVendorTaxTypeCode()))) {
0605: if (isParent) {
0606: putFieldError(
0607: VendorPropertyConstants.VENDOR_TAX_TYPE_CODE,
0608: VendorKeyConstants.ERROR_VENDOR_TAX_TYPE_CANNOT_BE_BLANK);
0609: }
0610: valid &= false;
0611: } else if (StringUtils.isBlank(vendorDetail.getVendorHeader()
0612: .getVendorTaxNumber())
0613: && !StringUtils.isBlank(vendorDetail.getVendorHeader()
0614: .getVendorTaxTypeCode())) {
0615: if (isParent) {
0616: putFieldError(
0617: VendorPropertyConstants.VENDOR_TAX_TYPE_CODE,
0618: VendorKeyConstants.ERROR_VENDOR_TAX_TYPE_CANNOT_BE_SET);
0619: }
0620: valid &= false;
0621: }
0622:
0623: if (!valid && !isParent) {
0624: putFieldError(
0625: VendorPropertyConstants.VENDOR_TAX_TYPE_CODE,
0626: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0627: }
0628:
0629: return valid;
0630: }
0631:
0632: /**
0633: * Validates the vendorName, vendorFirstName and vendorLastName fields according to these business rules: 1. At least one of the
0634: * three vendor name fields must be filled in. 2. Both of the two ways of entering vendor name (One vendor name field vs
0635: * VendorFirstName/VendorLastName) cannot be used 3. If either the vendor first name or the vendor last name have been entered,
0636: * the other must be entered.
0637: *
0638: * @param vendorDetail The VendorDetail object to be validated
0639: * @return boolean true if the vendorDetail passes this validation and false otherwise.
0640: */
0641: protected boolean validateVendorNames(VendorDetail vendorDetail) {
0642: boolean valid = true;
0643: if (StringUtils.isBlank(vendorDetail.getVendorName())) {
0644: // At least one of the three vendor name fields must be filled in.
0645: if (StringUtils.isBlank(vendorDetail.getVendorFirstName())
0646: && StringUtils.isBlank(vendorDetail
0647: .getVendorLastName())) {
0648:
0649: putFieldError(VendorPropertyConstants.VENDOR_NAME,
0650: VendorKeyConstants.ERROR_VENDOR_NAME_REQUIRED);
0651: valid &= false;
0652: }
0653: // If either the vendor first name or the vendor last name have been entered, the other must be entered.
0654: else if (StringUtils.isBlank(vendorDetail
0655: .getVendorFirstName())
0656: || StringUtils.isBlank(vendorDetail
0657: .getVendorLastName())) {
0658:
0659: putFieldError(
0660: VendorPropertyConstants.VENDOR_NAME,
0661: VendorKeyConstants.ERROR_VENDOR_BOTH_NAME_REQUIRED);
0662: valid &= false;
0663: }
0664: } else {
0665: // Both of the two ways of entering vendor name (One vendor name field vs VendorFirstName/VendorLastName) cannot be used
0666: if (!StringUtils.isBlank(vendorDetail.getVendorFirstName())
0667: || !StringUtils.isBlank(vendorDetail
0668: .getVendorLastName())) {
0669:
0670: putFieldError(VendorPropertyConstants.VENDOR_NAME,
0671: VendorKeyConstants.ERROR_VENDOR_NAME_INVALID);
0672: valid &= false;
0673: }
0674: }
0675: return valid;
0676: }
0677:
0678: /**
0679: * Validates the ownership type codes that aren't allowed for the tax type of the vendor. The rules are : 1. If tax type is
0680: * "SSN", then check the ownership type against the allowed types for "SSN" in the Rules table. 2. If tax type is "FEIN", then
0681: * check the ownership type against the allowed types for "FEIN" in the Rules table. If the vendor is a parent and the
0682: * validation fails, display the actual error message. If the vendor is not a parent and the validation fails, display the error
0683: * message that the parent of this vendor needs to be changed, please contact Purchasing Dept.
0684: *
0685: * @param vendorDetail The VendorDetail object to be validated
0686: * @return boolean true if the ownership type is allowed and FALSE otherwise.
0687: */
0688: private boolean validateOwnershipTypeAllowed(
0689: VendorDetail vendorDetail) {
0690: boolean valid = true;
0691: boolean isParent = vendorDetail.isVendorParentIndicator();
0692: String ownershipTypeCode = vendorDetail.getVendorHeader()
0693: .getVendorOwnershipCode();
0694: String taxTypeCode = vendorDetail.getVendorHeader()
0695: .getVendorTaxTypeCode();
0696: if (StringUtils.isNotEmpty(ownershipTypeCode)
0697: && StringUtils.isNotEmpty(taxTypeCode)) {
0698: if (VendorConstants.TAX_TYPE_FEIN.equals(taxTypeCode)) {
0699: if (!SpringContext
0700: .getBean(ParameterService.class)
0701: .getParameterEvaluator(
0702: VendorDetail.class,
0703: VendorParameterConstants.PURAP_FEIN_ALLOWED_OWNERSHIP_TYPES,
0704: ownershipTypeCode).evaluationSucceeds()) {
0705: valid &= false;
0706: }
0707: } else if (VendorConstants.TAX_TYPE_SSN.equals(taxTypeCode)) {
0708: if (!SpringContext
0709: .getBean(ParameterService.class)
0710: .getParameterEvaluator(
0711: VendorDetail.class,
0712: VendorParameterConstants.PURAP_SSN_ALLOWED_OWNERSHIP_TYPES,
0713: ownershipTypeCode).evaluationSucceeds()) {
0714: valid &= false;
0715: }
0716: }
0717: }
0718: if (!valid && isParent) {
0719: putFieldError(
0720: VendorPropertyConstants.VENDOR_OWNERSHIP_CODE,
0721: VendorKeyConstants.ERROR_OWNERSHIP_TYPE_CODE_NOT_ALLOWED,
0722: new String[] {
0723: vendorDetail.getVendorHeader()
0724: .getVendorOwnership()
0725: .getVendorOwnershipDescription(),
0726: taxTypeCode });
0727: } else if (!valid && !isParent) {
0728: putFieldError(
0729: VendorPropertyConstants.VENDOR_OWNERSHIP_CODE,
0730: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0731: }
0732: return valid;
0733: }
0734:
0735: /**
0736: * Per code review 9/19, these business rules should be moved to the rule table. This method validates that the minimum order
0737: * amount is less than the minimum order amount constant that is currently defined in VendorConstants.java but someday should be
0738: * moved to APC.
0739: *
0740: * @param vendorDetail The VendorDetail object to be validated
0741: * @return booelan true if the vendorMinimumOrderAmount is less than the minimum order amount specified in the VendorConstants
0742: * (in the future the amount will be in APC).
0743: */
0744: private boolean validateMinimumOrderAmount(VendorDetail vendorDetail) {
0745: boolean valid = true;
0746: KualiDecimal minimumOrderAmount = vendorDetail
0747: .getVendorMinimumOrderAmount();
0748: if (minimumOrderAmount != null) {
0749: if (ObjectUtils.isNull(VENDOR_MIN_ORDER_AMOUNT)) {
0750: VENDOR_MIN_ORDER_AMOUNT = new KualiDecimal(
0751: SpringContext
0752: .getBean(ParameterService.class)
0753: .getParameterValue(
0754: VendorDetail.class,
0755: VendorParameterConstants.PURAP_VENDOR_MIN_ORDER_AMOUNT));
0756: }
0757: if ((VENDOR_MIN_ORDER_AMOUNT.compareTo(minimumOrderAmount) < 1)
0758: || (minimumOrderAmount.isNegative())) {
0759: putFieldError(
0760: VendorPropertyConstants.VENDOR_MIN_ORDER_AMOUNT,
0761: VendorKeyConstants.ERROR_VENDOR_MAX_MIN_ORDER_AMOUNT,
0762: VENDOR_MIN_ORDER_AMOUNT.toString());
0763: valid &= false;
0764: }
0765: }
0766: return valid;
0767: }
0768:
0769: /**
0770: * Validates that if the ownership category allowed indicator is false, the vendor does not have ownership category. It will
0771: * return false if the vendor contains ownership category. If the vendor is a parent and the validation fails, display the
0772: * actual error message. If the vendor is not a parent and the validation fails, display the error message that the parent of
0773: * this vendor needs to be changed, please contact Purchasing Dept.
0774: *
0775: * @param vendorDetail The VendorDetail to be validated
0776: * @return boolean true if the vendor does not contain ownership category and false otherwise
0777: */
0778: private boolean validateOwnershipCategory(VendorDetail vendorDetail) {
0779: boolean valid = true;
0780: boolean isParent = vendorDetail.isVendorParentIndicator();
0781: OwnershipType ot = vendorDetail.getVendorHeader()
0782: .getVendorOwnership();
0783: if (ot != null
0784: && !ot.getVendorOwnershipCategoryAllowedIndicator()) {
0785: if (ObjectUtils.isNotNull(vendorDetail.getVendorHeader()
0786: .getVendorOwnershipCategory())) {
0787: valid &= false;
0788: }
0789: }
0790: if (!valid && isParent) {
0791: putFieldError(
0792: VendorPropertyConstants.VENDOR_OWNERSHIP_CATEGORY_CODE,
0793: VendorKeyConstants.ERROR_OWNERSHIP_CATEGORY_CODE_NOT_ALLOWED,
0794: new String[] {
0795: vendorDetail
0796: .getVendorHeader()
0797: .getVendorOwnershipCategory()
0798: .getVendorOwnershipCategoryDescription(),
0799: vendorDetail.getVendorHeader()
0800: .getVendorOwnership()
0801: .getVendorOwnershipDescription() });
0802: } else if (!valid && !isParent) {
0803: putFieldError(
0804: VendorPropertyConstants.VENDOR_OWNERSHIP_CODE,
0805: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0806: }
0807: return valid;
0808: }
0809:
0810: /**
0811: * Calls the methods in TaxNumberService to validate the tax number for these business rules: 1. Tax number must be 9 digits and
0812: * cannot be all zeros (but can be blank). 2. First three digits of a SSN cannot be 000. 3. First three digits of a SSN cannot
0813: * be 666. 4. Middle two digits of a SSN cannot be 00. 5. Last four digits of a SSN cannot be 0000. 6. First two digits of a
0814: * FEIN cannot be 00. 7. Check system parameters for not allowed tax numbers
0815: *
0816: * @param vendorDetail The VendorDetail object to be validated
0817: * @return boolean true if the tax number is a valid tax number and false otherwise.
0818: */
0819: private boolean validateTaxNumberFromTaxNumberService(
0820: VendorDetail vendorDetail) {
0821: boolean valid = true;
0822: boolean isParent = vendorDetail.isVendorParentIndicator();
0823: String taxNumber = vendorDetail.getVendorHeader()
0824: .getVendorTaxNumber();
0825: String taxType = vendorDetail.getVendorHeader()
0826: .getVendorTaxTypeCode();
0827: if (!StringUtils.isEmpty(taxType)
0828: && !StringUtils.isEmpty(taxNumber)) {
0829: valid = SpringContext.getBean(TaxNumberService.class)
0830: .isValidTaxNumber(taxNumber, taxType);
0831: if (!valid && isParent) {
0832: putFieldError(
0833: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0834: VendorKeyConstants.ERROR_TAX_NUMBER_INVALID);
0835: }
0836: valid = SpringContext.getBean(TaxNumberService.class)
0837: .isAllowedTaxNumber(taxNumber);
0838: if (!valid && isParent) {
0839: putFieldError(
0840: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0841: VendorKeyConstants.ERROR_TAX_NUMBER_NOT_ALLOWED);
0842: }
0843: }
0844: if (!valid && !isParent) {
0845: putFieldError(
0846: VendorPropertyConstants.VENDOR_TAX_NUMBER,
0847: VendorKeyConstants.ERROR_VENDOR_PARENT_NEEDS_CHANGED);
0848: }
0849: return valid;
0850: }
0851:
0852: /**
0853: * Validates vendor address fields.
0854: *
0855: * @param document MaintenanceDocument
0856: * @return boolean false or true
0857: */
0858: boolean processAddressValidation(MaintenanceDocument document) {
0859: boolean valid = true;
0860: boolean validAddressType = false;
0861:
0862: List<VendorAddress> addresses = newVendor.getVendorAddresses();
0863:
0864: String vendorTypeCode = newVendor.getVendorHeader()
0865: .getVendorTypeCode();
0866: String vendorAddressTypeRequiredCode = newVendor
0867: .getVendorHeader().getVendorType()
0868: .getVendorAddressTypeRequiredCode();
0869:
0870: for (int i = 0; i < addresses.size(); i++) {
0871: VendorAddress address = addresses.get(i);
0872: String errorPath = MAINTAINABLE_ERROR_PREFIX
0873: + VendorPropertyConstants.VENDOR_ADDRESS + "[" + i
0874: + "]";
0875: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
0876:
0877: if (address.getVendorAddressTypeCode().equals(
0878: vendorAddressTypeRequiredCode)) {
0879: validAddressType = true;
0880: }
0881:
0882: valid &= checkFaxNumber(address);
0883: valid &= checkAddressCountryEmptyStateZip(address);
0884:
0885: GlobalVariables.getErrorMap()
0886: .removeFromErrorPath(errorPath);
0887: }
0888:
0889: // validate Address Type
0890:
0891: if (!StringUtils.isBlank(vendorTypeCode)
0892: && !StringUtils.isBlank(vendorAddressTypeRequiredCode)
0893: && !validAddressType) {
0894: String[] parameters = new String[] { vendorTypeCode,
0895: vendorAddressTypeRequiredCode };
0896: String vendorAddressTabPrefix = KFSConstants.ADD_PREFIX
0897: + "." + VendorPropertyConstants.VENDOR_ADDRESS
0898: + ".";
0899: putFieldError(vendorAddressTabPrefix
0900: + VendorPropertyConstants.VENDOR_ADDRESS_TYPE_CODE,
0901: VendorKeyConstants.ERROR_ADDRESS_TYPE, parameters);
0902: putFieldError(vendorAddressTabPrefix
0903: + VendorPropertyConstants.VENDOR_ADDRESS_LINE_1,
0904: KFSKeyConstants.ERROR_REQUIRED,
0905: KFSPropertyConstants.ADDRESS_LINE1);
0906: putFieldError(vendorAddressTabPrefix
0907: + VendorPropertyConstants.VENDOR_ADDRESS_CITY,
0908: KFSKeyConstants.ERROR_REQUIRED,
0909: KFSPropertyConstants.CITY);
0910: putFieldError(vendorAddressTabPrefix
0911: + VendorPropertyConstants.VENDOR_ADDRESS_COUNTRY,
0912: KFSKeyConstants.ERROR_REQUIRED,
0913: KFSPropertyConstants.COUNTRY_CODE);
0914: valid = false;
0915:
0916: }
0917:
0918: valid &= validateDefaultAddressCampus(newVendor);
0919:
0920: // Check to see if all divisions have one desired address for this vendor type
0921: Map fieldValues = new HashMap();
0922: fieldValues.put(
0923: VendorPropertyConstants.VENDOR_HEADER_GENERATED_ID,
0924: newVendor.getVendorHeaderGeneratedIdentifier());
0925: // Find all the addresses for this vendor and its divisions:
0926: List<VendorAddress> vendorDivisionAddresses = new ArrayList(
0927: SpringContext
0928: .getBean(BusinessObjectService.class)
0929: .findMatchingOrderBy(
0930: VendorAddress.class,
0931: fieldValues,
0932: VendorPropertyConstants.VENDOR_DETAIL_ASSIGNED_ID,
0933: true));
0934:
0935: // This set stores the vendorDetailedAssignedIds for the vendor divisions which is
0936: // bascically the division numbers 0, 1, 2, ...
0937: HashSet<Integer> vendorDetailedIds = new HashSet();
0938: // This set stores the vendor division numbers of the ones which have one address of the desired type
0939: HashSet<Integer> vendorDivisionsIdsWithDesiredAddressType = new HashSet();
0940:
0941: for (VendorAddress vendorDivisionAddress : vendorDivisionAddresses) {
0942: // We need to exclude the first one Since we already checked for this in valid AddressType above.
0943: if (vendorDivisionAddress
0944: .getVendorDetailAssignedIdentifier() != 0) {
0945: vendorDetailedIds.add(vendorDivisionAddress
0946: .getVendorDetailAssignedIdentifier());
0947: if (vendorDivisionAddress
0948: .getVendorAddressTypeCode()
0949: .equalsIgnoreCase(vendorAddressTypeRequiredCode)) {
0950: vendorDivisionsIdsWithDesiredAddressType
0951: .add(vendorDivisionAddress
0952: .getVendorDetailAssignedIdentifier());
0953: }
0954: }
0955: }
0956:
0957: // If the number of divisions with the desired address type is less than the number of divisions for his vendor
0958: if (vendorDivisionsIdsWithDesiredAddressType.size() < vendorDetailedIds
0959: .size()) {
0960:
0961: Iterator itr = vendorDetailedIds.iterator();
0962:
0963: Integer value;
0964: String vendorId;
0965:
0966: while (itr.hasNext()) {
0967: value = (Integer) itr.next();
0968: if (!vendorDivisionsIdsWithDesiredAddressType
0969: .contains(value)) {
0970: vendorId = newVendor
0971: .getVendorHeaderGeneratedIdentifier()
0972: .toString()
0973: + '-' + value.toString();
0974: String[] parameters = new String[] { vendorId,
0975: vendorTypeCode,
0976: vendorAddressTypeRequiredCode };
0977: putFieldError(
0978: VendorPropertyConstants.VENDOR_TYPE_CODE,
0979: VendorKeyConstants.ERROR_ADDRESS_TYPE_DIVISIONS,
0980: parameters);
0981: valid = false;
0982: }
0983: }
0984: }
0985:
0986: return valid;
0987:
0988: }
0989:
0990: /**
0991: * Validates that if US is selected for the country then the state and zip cannot be empty
0992: *
0993: * @param addresses VendorAddress which is being validated
0994: * @return boolean false if the country is United States and there is no state or zip code
0995: */
0996: boolean checkAddressCountryEmptyStateZip(VendorAddress address) {
0997:
0998: boolean valid = true;
0999: boolean noPriorErrMsg = true;
1000:
1001: Country country = address.getVendorCountry();
1002: if (ObjectUtils.isNotNull(country)
1003: && StringUtils.equals(
1004: KFSConstants.COUNTRY_CODE_UNITED_STATES,
1005: country.getPostalCountryCode())) {
1006:
1007: if ((ObjectUtils.isNull(address.getVendorState()) || StringUtils
1008: .isEmpty(address.getVendorState()
1009: .getPostalStateCode()))) {
1010: GlobalVariables.getErrorMap().putError(
1011: VendorPropertyConstants.VENDOR_ADDRESS_STATE,
1012: VendorKeyConstants.ERROR_US_REQUIRES_STATE);
1013: valid &= false;
1014: noPriorErrMsg = false;
1015: }
1016: // The error message here will be the same for both, and should not be repeated (KULPURAP-516).
1017: if (noPriorErrMsg
1018: && StringUtils.isEmpty(address.getVendorZipCode())) {
1019: GlobalVariables.getErrorMap().putError(
1020: VendorPropertyConstants.VENDOR_ADDRESS_ZIP,
1021: VendorKeyConstants.ERROR_US_REQUIRES_ZIP);
1022: valid &= false;
1023: }
1024: }
1025: return valid;
1026: }
1027:
1028: /**
1029: * Checks if the "allow default indicator" is true or false for this address.
1030: *
1031: * @param addresses VendorAddress which is being validated
1032: * @return boolean false or true
1033: */
1034:
1035: boolean findAllowDefaultAddressIndicatorHelper(
1036: VendorAddress vendorAddress) {
1037:
1038: AddressType addressType = new AddressType();
1039:
1040: addressType = vendorAddress.getVendorAddressType();
1041: if (ObjectUtils.isNull(addressType)) {
1042: return false;
1043: }
1044: // Retrieving the Default Address Indicator for this Address Type:
1045: return addressType.getVendorDefaultIndicator();
1046:
1047: }
1048:
1049: /**
1050: * If add button is selected on Default Address, checks if the allow default indicator is set to false for this address type
1051: * then it does not allow user to select a default address for this address and if it is true then it allows only one campus to
1052: * be default for this address.
1053: *
1054: * @param vendorDetail VendorDetail document
1055: * @param addedDefaultAddress VendorDefaultAddress which is being added
1056: * @param parent The VendorAddress which we are adding a default address to it
1057: * @return boolean false or true
1058: */
1059: boolean checkDefaultAddressCampus(VendorDetail vendorDetail,
1060: VendorDefaultAddress addedDefaultAddress,
1061: VendorAddress parent) {
1062: VendorAddress vendorAddress = parent;
1063: if (ObjectUtils.isNull(vendorAddress)) {
1064: return false;
1065: }
1066:
1067: int j = vendorDetail.getVendorAddresses()
1068: .indexOf(vendorAddress);
1069: String errorPath = MAINTAINABLE_ERROR_PREFIX
1070: + VendorPropertyConstants.VENDOR_ADDRESS + "[" + j
1071: + "]";
1072: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
1073:
1074: // Retrieving the Default Address Indicator for this Address Type:
1075: boolean allowDefaultAddressIndicator = findAllowDefaultAddressIndicatorHelper(vendorAddress);
1076: String addedAddressCampusCode = addedDefaultAddress
1077: .getVendorCampusCode();
1078: String addedAddressTypeCode = vendorAddress
1079: .getVendorAddressTypeCode();
1080:
1081: // if the selected address type does not allow defaults, then the user should not be allowed to
1082: // select the default indicator or add any campuses to the address
1083: if (allowDefaultAddressIndicator == false) {
1084: String[] parameters = new String[] { addedAddressTypeCode };
1085: GlobalVariables
1086: .getErrorMap()
1087: .putError(
1088: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS
1089: + "["
1090: + 0
1091: + "]."
1092: + VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_CAMPUS,
1093: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_CAMPUS_NOT_ALLOWED,
1094: parameters);
1095: return false;
1096: }
1097:
1098: List<VendorDefaultAddress> vendorDefaultAddresses = vendorAddress
1099: .getVendorDefaultAddresses();
1100: for (int i = 0; i < vendorDefaultAddresses.size(); i++) {
1101: VendorDefaultAddress vendorDefaultAddress = vendorDefaultAddresses
1102: .get(i);
1103: if (vendorDefaultAddress.getVendorCampusCode()
1104: .equalsIgnoreCase(addedAddressCampusCode)) {
1105: String[] parameters = new String[] {
1106: addedAddressCampusCode, addedAddressTypeCode };
1107: GlobalVariables
1108: .getErrorMap()
1109: .putError(
1110: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS
1111: + "["
1112: + i
1113: + "]."
1114: + VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_CAMPUS,
1115: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_CAMPUS,
1116: parameters);
1117: return false;
1118: }
1119: }
1120:
1121: return true;
1122: }
1123:
1124: /**
1125: * Checks if the allow default indicator is set to false for this address the default indicator cannot be set to true/yes. If
1126: * "allow default indicator" is set to true/yes for address type, one address must have the default indicator set (no more, no
1127: * less) and only one campus to be set as default for this address.
1128: *
1129: * @param vendorDetail VendorDetail document
1130: * @return boolean false or true
1131: */
1132:
1133: boolean validateDefaultAddressCampus(VendorDetail vendorDetail) {
1134: List<VendorAddress> vendorAddresses = vendorDetail
1135: .getVendorAddresses();
1136: String addressTypeCode;
1137: String campusCode;
1138: boolean valid = true;
1139: boolean previousValue = false;
1140:
1141: // This is a HashMap to store the default Address Type Codes and their associated default Indicator
1142: HashMap addressTypeCodeDefaultIndicator = new HashMap();
1143:
1144: // This is a HashMap to store Address Type Codes and Address Campus Codes for Default Addresses
1145: HashMap addressTypeDefaultCampus = new HashMap();
1146:
1147: // This is a HashSet for storing only the Address Type Codes which have at least one default Indicator set to true
1148: HashSet addressTypesHavingDefaultTrue = new HashSet();
1149:
1150: int i = 0;
1151: for (VendorAddress address : vendorAddresses) {
1152: addressTypeCode = address.getVendorAddressTypeCode();
1153: String errorPath = MAINTAINABLE_ERROR_PREFIX
1154: + VendorPropertyConstants.VENDOR_ADDRESS + "[" + i
1155: + "]";
1156: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
1157: String[] parameters = new String[] { addressTypeCode };
1158:
1159: // If "allow default indicator" is set to true/yes for address type, one address must have the default indicator set (no
1160: // more, no less).
1161: // For example, if a vendor contains three PO type addresses and the PO address type is set to allow defaults in the
1162: // address type table,
1163: // then only one of these PO addresses can have the default indicator set to true/yes.
1164:
1165: if (findAllowDefaultAddressIndicatorHelper(address)) {
1166: if (address.isVendorDefaultAddressIndicator()) {
1167: addressTypesHavingDefaultTrue.add(addressTypeCode);
1168: }
1169: if (!addressTypeCodeDefaultIndicator.isEmpty()
1170: && addressTypeCodeDefaultIndicator
1171: .containsKey(addressTypeCode)) {
1172: previousValue = ((Boolean) addressTypeCodeDefaultIndicator
1173: .get(addressTypeCode)).booleanValue();
1174: }
1175:
1176: if (addressTypeCodeDefaultIndicator.put(
1177: addressTypeCode, address
1178: .isVendorDefaultAddressIndicator()) != null
1179: && previousValue
1180: && address.isVendorDefaultAddressIndicator()) {
1181: GlobalVariables
1182: .getErrorMap()
1183: .putError(
1184: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_INDICATOR,
1185: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_INDICATOR,
1186: parameters);
1187: valid = false;
1188: }
1189:
1190: }
1191: // If "allow default indicator" is set to false/no for address type, the default indicator cannot be set to true/yes.
1192: else {
1193: if (address.isVendorDefaultAddressIndicator()) {
1194: GlobalVariables
1195: .getErrorMap()
1196: .putError(
1197: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_INDICATOR,
1198: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_ADDRESS_NOT_ALLOWED,
1199: parameters);
1200: valid = false;
1201: }
1202:
1203: }
1204:
1205: List<VendorDefaultAddress> vendorDefaultAddresses = address
1206: .getVendorDefaultAddresses();
1207:
1208: // If "allow default indicator" is set to true/yes for address type, a campus can only be set on one of each type of
1209: // Address.
1210: // For example, Bloomington can not be included in the campus list for two PO type addresses.
1211: // Each campus can only have one default address.
1212: int j = 0;
1213: for (VendorDefaultAddress defaultAddress : vendorDefaultAddresses) {
1214: campusCode = (String) addressTypeDefaultCampus.put(
1215: addressTypeCode, defaultAddress
1216: .getVendorCampusCode());
1217: if (StringUtils.isNotBlank(campusCode)
1218: && campusCode.equalsIgnoreCase(defaultAddress
1219: .getVendorCampusCode())) {
1220: String[] newParameters = new String[] {
1221: defaultAddress.getVendorCampusCode(),
1222: addressTypeCode };
1223: GlobalVariables
1224: .getErrorMap()
1225: .putError(
1226: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS
1227: + "["
1228: + j
1229: + "]."
1230: + VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_CAMPUS,
1231: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_CAMPUS,
1232: newParameters);
1233: valid = false;
1234: }
1235: j++;
1236: }
1237: i++;
1238: GlobalVariables.getErrorMap()
1239: .removeFromErrorPath(errorPath);
1240: }
1241:
1242: // If "allow default indicator" is set to true/yes for address type, one address must have the default indicator set to true
1243: if (!addressTypeCodeDefaultIndicator.isEmpty()) {
1244: Set<String> addressTypes = addressTypeCodeDefaultIndicator
1245: .keySet();
1246:
1247: for (String addressType : addressTypes) {
1248: if (!addressTypesHavingDefaultTrue
1249: .contains(addressType)) {
1250: String[] parameters = new String[] { addressType };
1251: GlobalVariables
1252: .getErrorMap()
1253: .putError(
1254: VendorPropertyConstants.VENDOR_DEFAULT_ADDRESS_INDICATOR,
1255: VendorKeyConstants.ERROR_ADDRESS_DEFAULT_INDICATOR,
1256: parameters);
1257: valid = false;
1258: }
1259: }
1260: }
1261:
1262: return valid;
1263: }
1264:
1265: /**
1266: * Validates that the Vendor Fax Number is a valid phone number.
1267: *
1268: * @param addresses VendorAddress instance
1269: * @return boolean false or true
1270: */
1271: boolean checkFaxNumber(VendorAddress address) {
1272: boolean valid = true;
1273: String faxNumber = address.getVendorFaxNumber();
1274: if (StringUtils.isNotEmpty(faxNumber)
1275: && !SpringContext.getBean(PhoneNumberService.class)
1276: .isValidPhoneNumber(faxNumber)) {
1277: GlobalVariables.getErrorMap().putError(
1278: VendorPropertyConstants.VENDOR_FAX_NUMBER,
1279: VendorKeyConstants.ERROR_FAX_NUMBER);
1280: valid &= false;
1281: }
1282: return valid;
1283: }
1284:
1285: /**
1286: * A stub method as placeholder for future Contact Validation
1287: *
1288: * @param document MaintenanceDocument instance
1289: * @return boolean false or true
1290: */
1291: private boolean processContactValidation(
1292: MaintenanceDocument document) {
1293: boolean valid = true;
1294: // leaving stub method here as placeholder for future Contact Validation
1295: return valid;
1296: }
1297:
1298: /**
1299: * Validates vendor customer numbers
1300: *
1301: * @param document MaintenanceDocument instance
1302: * @return boolean false or true
1303: */
1304: private boolean processCustomerNumberValidation(
1305: MaintenanceDocument document) {
1306: boolean valid = true;
1307:
1308: List<VendorCustomerNumber> customerNumbers = newVendor
1309: .getVendorCustomerNumbers();
1310: for (VendorCustomerNumber customerNumber : customerNumbers) {
1311: valid &= validateVendorCustomerNumber(customerNumber);
1312: }
1313: return valid;
1314: }
1315:
1316: /**
1317: * Validates vendor customer number. The chart and org must exist in the database.
1318: *
1319: * @param customerNumber VendorCustomerNumber
1320: * @return boolean false or true
1321: */
1322: boolean validateVendorCustomerNumber(
1323: VendorCustomerNumber customerNumber) {
1324: boolean valid = true;
1325:
1326: // The chart and org must exist in the database.
1327: String chartOfAccountsCode = customerNumber
1328: .getChartOfAccountsCode();
1329: String orgCode = customerNumber.getVendorOrganizationCode();
1330: if (!StringUtils.isBlank(chartOfAccountsCode)
1331: && !StringUtils.isBlank(orgCode)) {
1332: Map chartOrgMap = new HashMap();
1333: chartOrgMap.put("chartOfAccountsCode", chartOfAccountsCode);
1334: if (SpringContext.getBean(BusinessObjectService.class)
1335: .countMatching(Chart.class, chartOrgMap) < 1) {
1336: GlobalVariables
1337: .getErrorMap()
1338: .putError(
1339: VendorPropertyConstants.VENDOR_CUSTOMER_NUMBER_CHART_OF_ACCOUNTS_CODE,
1340: KFSKeyConstants.ERROR_EXISTENCE,
1341: chartOfAccountsCode);
1342: valid &= false;
1343: }
1344: chartOrgMap.put("organizationCode", orgCode);
1345: if (SpringContext.getBean(BusinessObjectService.class)
1346: .countMatching(Org.class, chartOrgMap) < 1) {
1347: GlobalVariables
1348: .getErrorMap()
1349: .putError(
1350: VendorPropertyConstants.VENDOR_CUSTOMER_NUMBER_ORGANIZATION_CODE,
1351: KFSKeyConstants.ERROR_EXISTENCE,
1352: orgCode);
1353: valid &= false;
1354: }
1355: }
1356: return valid;
1357: }
1358:
1359: /**
1360: * Validates vendor contract. If the vendorContractAllowedIndicator is false, it cannot have vendor contracts, then return false
1361: *
1362: * @param document MaintenanceDocument
1363: * @return boolean false or true
1364: */
1365: private boolean processContractValidation(
1366: MaintenanceDocument document) {
1367: boolean valid = true;
1368: List<VendorContract> contracts = newVendor.getVendorContracts();
1369: if (ObjectUtils.isNull(contracts)) {
1370: return valid;
1371: }
1372:
1373: // If the vendorContractAllowedIndicator is false, it cannot have vendor contracts, return false;
1374: if (contracts.size() > 0
1375: && !newVendor.getVendorHeader().getVendorType()
1376: .isVendorContractAllowedIndicator()) {
1377: valid = false;
1378: String errorPath = MAINTAINABLE_ERROR_PREFIX
1379: + VendorPropertyConstants.VENDOR_CONTRACT + "[0]";
1380: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
1381: GlobalVariables
1382: .getErrorMap()
1383: .putError(
1384: VendorPropertyConstants.VENDOR_CONTRACT_NAME,
1385: VendorKeyConstants.ERROR_VENDOR_CONTRACT_NOT_ALLOWED);
1386: GlobalVariables.getErrorMap()
1387: .removeFromErrorPath(errorPath);
1388: return valid;
1389: }
1390:
1391: for (int i = 0; i < contracts.size(); i++) {
1392: VendorContract contract = contracts.get(i);
1393:
1394: String errorPath = MAINTAINABLE_ERROR_PREFIX
1395: + VendorPropertyConstants.VENDOR_CONTRACT + "[" + i
1396: + "]";
1397: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
1398:
1399: valid &= validateVendorContractPOLimitAndExcludeFlagCombination(contract);
1400: valid &= validateVendorContractBeginEndDates(contract);
1401:
1402: GlobalVariables.getErrorMap()
1403: .removeFromErrorPath(errorPath);
1404: }
1405: return valid;
1406: }
1407:
1408: /**
1409: * Validates that the proper combination of Exclude Indicator and APO Amount is present on a vendor contract. Do not perform
1410: * this validation on Contract add line as the user cannot currently enter the sub-collection of contract-orgs so we should not
1411: * force this until the document is submitted. The rules are : 1. Must enter a Default APO Limit or at least one organization
1412: * with an APO Amount. 2. If the Exclude Indicator for an organization is N, an organization APO Amount is required. 3. If the
1413: * Exclude Indicator for an organization is Y, the organization APO Amount is not allowed.
1414: *
1415: * @param contract VendorContract
1416: * @return boolean true if the proper combination of Exclude Indicator and APO Amount is present, otherwise flase.
1417: */
1418: boolean validateVendorContractPOLimitAndExcludeFlagCombination(
1419: VendorContract contract) {
1420: boolean valid = true;
1421: boolean NoOrgHasApoLimit = true;
1422:
1423: List<VendorContractOrganization> organizations = contract
1424: .getVendorContractOrganizations();
1425: if (ObjectUtils.isNotNull(organizations)) {
1426: int organizationCounter = 0;
1427: for (VendorContractOrganization organization : organizations) {
1428: if (ObjectUtils.isNotNull(organization
1429: .getVendorContractPurchaseOrderLimitAmount())) {
1430: NoOrgHasApoLimit = false;
1431: }
1432: valid &= validateVendorContractOrganization(organization);
1433: organizationCounter++;
1434: }
1435: }
1436: if (NoOrgHasApoLimit
1437: && ObjectUtils.isNull(contract
1438: .getOrganizationAutomaticPurchaseOrderLimit())) {
1439: // Rule #1 in the above java doc has been violated.
1440: GlobalVariables
1441: .getErrorMap()
1442: .putError(
1443: VendorPropertyConstants.VENDOR_CONTRACT_DEFAULT_APO_LIMIT,
1444: VendorKeyConstants.ERROR_VENDOR_CONTRACT_NO_APO_LIMIT);
1445: valid &= false;
1446: }
1447: return valid;
1448: }
1449:
1450: /**
1451: * Validates that: 1. If the VendorContractBeginningDate is entered then the VendorContractEndDate is also entered, and vice
1452: * versa. 2. If both dates are entered, the VendorContractBeginningDate is before the VendorContractEndDate. The date fields are
1453: * required so we should know that we have valid dates.
1454: *
1455: * @param contract VendorContract
1456: * @return boolean true if the beginning date is before the end date, false if only one date is entered or the beginning date is
1457: * after the end date.
1458: */
1459: boolean validateVendorContractBeginEndDates(VendorContract contract) {
1460: boolean valid = true;
1461:
1462: if (ObjectUtils.isNotNull(contract
1463: .getVendorContractBeginningDate())
1464: && ObjectUtils.isNull(contract
1465: .getVendorContractEndDate())) {
1466: GlobalVariables
1467: .getErrorMap()
1468: .putError(
1469: VendorPropertyConstants.VENDOR_CONTRACT_END_DATE,
1470: VendorKeyConstants.ERROR_VENDOR_CONTRACT_BEGIN_DATE_NO_END_DATE);
1471: valid &= false;
1472: } else {
1473: if (ObjectUtils.isNull(contract
1474: .getVendorContractBeginningDate())
1475: && ObjectUtils.isNotNull(contract
1476: .getVendorContractEndDate())) {
1477: GlobalVariables
1478: .getErrorMap()
1479: .putError(
1480: VendorPropertyConstants.VENDOR_CONTRACT_BEGIN_DATE,
1481: VendorKeyConstants.ERROR_VENDOR_CONTRACT_END_DATE_NO_BEGIN_DATE);
1482: valid &= false;
1483: }
1484: }
1485: if (valid
1486: && ObjectUtils.isNotNull(contract
1487: .getVendorContractBeginningDate())
1488: && ObjectUtils.isNotNull(contract
1489: .getVendorContractEndDate())) {
1490: if (contract.getVendorContractBeginningDate().after(
1491: contract.getVendorContractEndDate())) {
1492: GlobalVariables
1493: .getErrorMap()
1494: .putError(
1495: VendorPropertyConstants.VENDOR_CONTRACT_BEGIN_DATE,
1496: VendorKeyConstants.ERROR_VENDOR_CONTRACT_BEGIN_DATE_AFTER_END);
1497: valid &= false;
1498: }
1499: }
1500:
1501: return valid;
1502: }
1503:
1504: /**
1505: * Validates a vendor contract organization. The rules are : 1. If the Exclude Indicator for the organization is N, an
1506: * organization APO Amount is required. 2. If the Exclude Indicator for the organization is Y, an organization APO Amount is not
1507: * allowed. 3. The chart and org for the organization must exist in the database.
1508: *
1509: * @param organization VendorContractOrganization
1510: * @return boolean true if these three rules are passed, otherwise false.
1511: */
1512: boolean validateVendorContractOrganization(
1513: VendorContractOrganization organization) {
1514: boolean valid = true;
1515:
1516: boolean isExcluded = organization
1517: .isVendorContractExcludeIndicator();
1518: if (isExcluded) {
1519: if (ObjectUtils.isNotNull(organization
1520: .getVendorContractPurchaseOrderLimitAmount())) {
1521: // Rule #2 in the above java doc has been violated.
1522: GlobalVariables
1523: .getErrorMap()
1524: .putError(
1525: VendorPropertyConstants.VENDOR_CONTRACT_ORGANIZATION_APO_LIMIT,
1526: VendorKeyConstants.ERROR_VENDOR_CONTRACT_ORG_EXCLUDED_WITH_APO_LIMIT);
1527: valid &= false;
1528: }
1529: } else { // isExcluded = false
1530: if (ObjectUtils.isNull(organization
1531: .getVendorContractPurchaseOrderLimitAmount())) {
1532: // Rule #1 in the above java doc has been violated.
1533: GlobalVariables
1534: .getErrorMap()
1535: .putError(
1536: VendorPropertyConstants.VENDOR_CONTRACT_ORGANIZATION_APO_LIMIT,
1537: VendorKeyConstants.ERROR_VENDOR_CONTRACT_ORG_NOT_EXCLUDED_NO_APO_LIMIT);
1538: valid &= false;
1539: }
1540: }
1541:
1542: // The chart and org must exist in the database.
1543: String chartOfAccountsCode = organization
1544: .getChartOfAccountsCode();
1545: String orgCode = organization.getOrganizationCode();
1546: if (!StringUtils.isBlank(chartOfAccountsCode)
1547: && !StringUtils.isBlank(orgCode)) {
1548: Map chartOrgMap = new HashMap();
1549: chartOrgMap.put("chartOfAccountsCode", chartOfAccountsCode);
1550: if (SpringContext.getBean(BusinessObjectService.class)
1551: .countMatching(Chart.class, chartOrgMap) < 1) {
1552: GlobalVariables
1553: .getErrorMap()
1554: .putError(
1555: VendorPropertyConstants.VENDOR_CONTRACT_CHART_OF_ACCOUNTS_CODE,
1556: KFSKeyConstants.ERROR_EXISTENCE,
1557: chartOfAccountsCode);
1558: valid &= false;
1559: }
1560: chartOrgMap.put("organizationCode", orgCode);
1561: if (SpringContext.getBean(BusinessObjectService.class)
1562: .countMatching(Org.class, chartOrgMap) < 1) {
1563: GlobalVariables
1564: .getErrorMap()
1565: .putError(
1566: VendorPropertyConstants.VENDOR_CONTRACT_ORGANIZATION_CODE,
1567: KFSKeyConstants.ERROR_EXISTENCE,
1568: orgCode);
1569: valid &= false;
1570: }
1571: }
1572:
1573: return valid;
1574: }
1575:
1576: /**
1577: * Validates business rules for VendorDetail document collection add lines. Add lines are the initial lines on a collections,
1578: * i.e. the ones next to the "Add" button
1579: *
1580: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.core.document.MaintenanceDocument,
1581: * java.lang.String, org.kuali.core.bo.PersistableBusinessObject)
1582: */
1583: @Override
1584: public boolean processCustomAddCollectionLineBusinessRules(
1585: MaintenanceDocument document, String collectionName,
1586: PersistableBusinessObject bo) {
1587: boolean success = true;
1588:
1589: // this incoming bo needs to be refreshed because it doesn't have its subobjects setup
1590: bo.refreshNonUpdateableReferences();
1591:
1592: if (bo instanceof VendorAddress) {
1593: VendorAddress address = (VendorAddress) bo;
1594: success &= checkAddressCountryEmptyStateZip(address);
1595: VendorDetail vendorDetail = (VendorDetail) document
1596: .getNewMaintainableObject().getBusinessObject();
1597:
1598: }
1599: if (bo instanceof VendorContract) {
1600: VendorContract contract = (VendorContract) bo;
1601: success &= validateVendorContractBeginEndDates(contract);
1602: }
1603: if (bo instanceof VendorContractOrganization) {
1604: VendorContractOrganization contractOrg = (VendorContractOrganization) bo;
1605: success &= validateVendorContractOrganization(contractOrg);
1606: }
1607: if (bo instanceof VendorCustomerNumber) {
1608: VendorCustomerNumber customerNumber = (VendorCustomerNumber) bo;
1609: success &= validateVendorCustomerNumber(customerNumber);
1610: }
1611: if (bo instanceof VendorDefaultAddress) {
1612: VendorDefaultAddress defaultAddress = (VendorDefaultAddress) bo;
1613: String parentName = StringUtils.substringBeforeLast(
1614: collectionName, ".");
1615: VendorAddress parent = (VendorAddress) ObjectUtils
1616: .getPropertyValue(this .getNewBo(), parentName);
1617: VendorDetail vendorDetail = (VendorDetail) document
1618: .getNewMaintainableObject().getBusinessObject();
1619: success &= checkDefaultAddressCampus(vendorDetail,
1620: defaultAddress, parent);
1621: }
1622:
1623: return success;
1624: }
1625:
1626: /**
1627: * Validates the rule that if a document has a federal witholding tax begin date and end date, the begin date should come before
1628: * the end date.
1629: *
1630: * @param vdDocument VendorDetail
1631: * @return boolean false or true
1632: */
1633: private boolean validateVendorWithholdingTaxDates(
1634: VendorDetail vdDocument) {
1635: boolean valid = true;
1636: DateTimeService dateTimeService = SpringContext
1637: .getBean(DateTimeService.class);
1638:
1639: Date beginDate = vdDocument.getVendorHeader()
1640: .getVendorFederalWithholdingTaxBeginningDate();
1641: Date endDate = vdDocument.getVendorHeader()
1642: .getVendorFederalWithholdingTaxEndDate();
1643: if (ObjectUtils.isNotNull(beginDate)
1644: && ObjectUtils.isNotNull(endDate)) {
1645: if (dateTimeService.dateDiff(beginDate, endDate, false) <= 0) {
1646: putFieldError(
1647: VendorPropertyConstants.VENDOR_FEDERAL_WITHOLDING_TAX_BEGINNING_DATE,
1648: VendorKeyConstants.ERROR_VENDOR_TAX_BEGIN_DATE_AFTER_END);
1649: valid &= false;
1650: }
1651: }
1652: return valid;
1653:
1654: }
1655:
1656: /**
1657: * Validates the rule that both w9 received and w-8ben cannot be set to yes
1658: *
1659: * @param vdDocument VendorDetail
1660: * @return boolean false or true
1661: */
1662: private boolean validateVendorW8BenOrW9ReceivedIndicator(
1663: VendorDetail vdDocument) {
1664: boolean valid = true;
1665:
1666: if (ObjectUtils.isNotNull(vdDocument.getVendorHeader()
1667: .getVendorW9ReceivedIndicator())
1668: && ObjectUtils.isNotNull(vdDocument.getVendorHeader()
1669: .getVendorW8BenReceivedIndicator())
1670: && vdDocument.getVendorHeader()
1671: .getVendorW9ReceivedIndicator()
1672: && vdDocument.getVendorHeader()
1673: .getVendorW8BenReceivedIndicator()) {
1674: putFieldError(
1675: VendorPropertyConstants.VENDOR_W9_RECEIVED_INDICATOR,
1676: VendorKeyConstants.ERROR_VENDOR_W9_AND_W8_RECEIVED_INDICATOR_BOTH_TRUE);
1677: valid &= false;
1678: }
1679: return valid;
1680:
1681: }
1682: }
|