001package org.kuali.ole.deliver.rule;
002
003import org.apache.cxf.common.util.StringUtils;
004import org.kuali.ole.OLEConstants;
005import org.kuali.ole.deliver.bo.OleAddressBo;
006import org.kuali.ole.deliver.bo.OleEntityAddressBo;
007import org.kuali.ole.deliver.bo.OlePatronDocument;
008import org.kuali.rice.core.api.util.RiceKeyConstants;
009import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
010import org.kuali.rice.coreservice.api.parameter.Parameter;
011import org.kuali.rice.coreservice.api.parameter.ParameterKey;
012import org.kuali.rice.kim.api.identity.IdentityService;
013import org.kuali.rice.kim.api.identity.entity.EntityDefault;
014import org.kuali.rice.kim.api.services.KimApiServiceLocator;
015import org.kuali.rice.kim.impl.identity.address.EntityAddressBo;
016import org.kuali.rice.kim.impl.identity.affiliation.EntityAffiliationBo;
017import org.kuali.rice.kim.impl.identity.email.EntityEmailBo;
018import org.kuali.rice.kim.impl.identity.employment.EntityEmploymentBo;
019import org.kuali.rice.kim.impl.identity.entity.EntityBo;
020import org.kuali.rice.kim.impl.identity.name.EntityNameBo;
021import org.kuali.rice.kim.impl.identity.phone.EntityPhoneBo;
022import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
023import org.kuali.rice.kim.service.UiDocumentService;
024import org.kuali.rice.krad.maintenance.MaintenanceDocument;
025import org.kuali.rice.krad.rules.MaintenanceDocumentRuleBase;
026import org.kuali.rice.krad.service.KRADServiceLocator;
027import org.kuali.rice.krad.util.GlobalVariables;
028import org.kuali.rice.krad.util.KRADConstants;
029import java.util.Date;
030import java.util.HashMap;
031import java.util.List;
032import java.util.Map;
033import java.util.regex.Matcher;
034import java.util.regex.Pattern;
035
036/**
037 * OlePatronDocumentRule performs validation for OlePatronDocument..
038 */
039public class OlePatronDocumentRule extends MaintenanceDocumentRuleBase {
040
041    protected UiDocumentService uiDocumentService;
042    protected IdentityService identityService;
043
044    /**
045     * This method validates the patron object and returns boolean value
046     *
047     * @param document
048     * @return isValid
049     */
050
051    protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
052        LOG.debug(" Inside processCustomSaveDocumentBusinessRule");
053        boolean isValid = true;
054        OlePatronDocument patronDocument = (OlePatronDocument) document.getNewMaintainableObject().getDataObject();
055        isValid &= validateBorrowerType(patronDocument);
056        isValid &= checkName(patronDocument);
057        EntityDefault origEntity = null;
058        if (patronDocument.getOlePatronId() != null) {
059            origEntity = getIdentityService().getEntityDefault(patronDocument.getOlePatronId());
060        }
061        boolean isCreatingNew = origEntity == null ? true : false;
062
063        isValid &= validateEntityInformation(isCreatingNew, patronDocument);
064        isValid &= validateBarcode(patronDocument);
065        isValid &= checkDuplicateBarcode(patronDocument);
066        isValid &= validateAddress(patronDocument, "oleEntityAddressBo");
067        isValid &= validateRequiredField(patronDocument);
068        isValid &= validatePatronName(patronDocument);
069        if (LOG.isDebugEnabled()) {
070            LOG.debug(" DocumentBusinessRule for patron record is " + isValid);
071        }
072        return isValid;
073    }
074
075    /**
076     * this method check the borrowerType property and returns boolean value
077     *
078     * @param patronDoc
079     * @return valid
080     */
081    protected boolean validateBorrowerType(OlePatronDocument patronDoc) {
082        boolean valid = true;
083        if (StringUtils.isEmpty(patronDoc.getBorrowerType())) {
084            this.putFieldError("dataObject.borrowerType", "error.field.required");
085            valid = false;
086        }
087        return valid;
088    }
089
090    /**
091     * this method validates the name object and returns boolean value
092     *
093     * @param patronDoc
094     * @return valid
095     */
096    protected boolean checkName(OlePatronDocument patronDoc) {
097        boolean valid = true;
098        if (StringUtils.isEmpty(patronDoc.getName().getFirstName())) {
099            this.putFieldError("dataObject.name.firstName", "error.field.required");
100            valid = false;
101        }
102        if (StringUtils.isEmpty(patronDoc.getName().getLastName())) {
103            this.putFieldError("dataObject.name.lastName", "error.field.required");
104            valid = false;
105        }
106
107        return valid;
108    }
109
110    /**
111     * This method validates the phone,address,and the email object in the patron document
112     *
113     * @param isCreatingNew
114     * @param patronDoc
115     * @return valid(boolean)
116     */
117    protected boolean validateEntityInformation(boolean isCreatingNew, OlePatronDocument patronDoc) {
118        boolean valid = true;
119        boolean canOverridePrivacyPreferences = getUIDocumentService().canOverrideEntityPrivacyPreferences(GlobalVariables.getUserSession().getPrincipalId(), null);
120        /*if(isCreatingNew || canOverridePrivacyPreferences) {*/
121        List<OleEntityAddressBo> addressBoList = patronDoc.getOleEntityAddressBo();
122        List<EntityEmailBo> emailBoList = patronDoc.getEmails();
123        List<EntityPhoneBo> phoneBoList = patronDoc.getPhones();
124        if (addressBoList.size() == 1) {
125            OleEntityAddressBo oleEntityAddressBo = addressBoList.get(0);
126            oleEntityAddressBo.getEntityAddressBo().setDefaultValue(true);
127        }
128        if (emailBoList.size() == 1) {
129            EntityEmailBo entityEmailBo = emailBoList.get(0);
130            entityEmailBo.setDefaultValue(true);
131        }
132        if (phoneBoList.size() == 1) {
133            EntityPhoneBo entityPhoneBo = phoneBoList.get(0);
134            entityPhoneBo.setDefaultValue(true);
135        }
136        if (!checkPhoneMultipleDefault(patronDoc.getPhones(), "phones")) {
137            GlobalVariables.getMessageMap().putErrorForSectionId(OLEConstants.OlePatron.PHONE_SECTION_ID, OLEConstants.OlePatron.ERROR_SELECTION_PREFERRED_PHONE);
138            valid &= false;
139        }
140        if (!checkAddressMultipleDefault(patronDoc.getOleEntityAddressBo(), "oleEntityAddressBo")) {
141            GlobalVariables.getMessageMap().putErrorForSectionId(OLEConstants.OlePatron.ADDRESS_SECTION_ID, OLEConstants.OlePatron.ERROR_SELECTION_PREFERRED_ADDRESS);
142            valid &= false;
143        }
144        if (!checkAddressMultipleDeliverAddress(patronDoc.getOleEntityAddressBo(), "oleEntityAddressBo")) {
145            GlobalVariables.getMessageMap().putErrorForSectionId(OLEConstants.OlePatron.ADDRESS_SECTION_ID, OLEConstants.OlePatron.ERROR_SELECTION_PREFERRED_DELIVER_ADDRESS);
146            valid &= false;
147        }
148
149        if (!checkEmailMultipleDefault(patronDoc.getEmails(), "emails")) {
150            GlobalVariables.getMessageMap().putErrorForSectionId(OLEConstants.OlePatron.EMAIL_SECTION_ID, OLEConstants.OlePatron.ERROR_SELECTION_PREFERRED_EMAIL);
151            valid &= false;
152        }
153        return valid;
154    }
155
156    /**
157     * This method validates the barcode number in the patron document
158     *
159     * @param patronDoc
160     * @return valid(boolean)
161     */
162    protected boolean validateBarcode(OlePatronDocument patronDoc) {
163        boolean valid = true;
164        if (StringUtils.isEmpty(patronDoc.getBarcode())) {
165            this.putFieldError("dataObject.barcode", "error.field.required");
166            valid = false;
167        }
168        return valid;
169    }
170
171    /**
172     * This method validates the duplicate barcode number in the patron document
173     *
174     * @param patronDoc
175     * @return valid(boolean)
176     */
177    protected boolean checkDuplicateBarcode(OlePatronDocument patronDoc) {
178        boolean valid = true;
179        Map barcodeMap = new HashMap();
180        barcodeMap.put(OLEConstants.OlePatron.BARCODE, patronDoc.getBarcode());
181        List<OlePatronDocument> olePatronDocuments = (List<OlePatronDocument>) KRADServiceLocator.getBusinessObjectService().findMatching(OlePatronDocument.class, barcodeMap);
182        if (olePatronDocuments.size() > 0) {
183            for (OlePatronDocument olePatronDocument : olePatronDocuments) {
184                if (patronDoc.getOlePatronId() == null || !(patronDoc.getOlePatronId().equals(olePatronDocument.getOlePatronId()))) {
185                    this.putFieldError("dataObject.barcode", "error.barcode.duplicate");
186                    valid = false;
187                }
188            }
189        }
190        return valid;
191    }
192
193
194    /**
195     * Gets the value of uiDocumentService property
196     *
197     * @return uiDocumentService(UiDocumentService)
198     */
199    public UiDocumentService getUIDocumentService() {
200        if (uiDocumentService == null) {
201            uiDocumentService = KIMServiceLocatorInternal.getUiDocumentService();
202        }
203        return uiDocumentService;
204    }
205
206    /**
207     * this method validates the phone object for default value
208     *
209     * @param phoneBoList
210     * @param listName
211     * @return valid
212     */
213    protected boolean checkPhoneMultipleDefault(List<EntityPhoneBo> phoneBoList, String listName) {
214        boolean valid = true;
215        boolean isDefaultSet = false;
216        int i = 0;
217        for (EntityPhoneBo phone : phoneBoList) {
218            if (phone.isDefaultValue()) {
219                if (isDefaultSet) {
220                    this.putFieldError("dataObject." + listName + "[" + i + "].defaultValue", RiceKeyConstants.ERROR_MULTIPLE_DEFAULT_SELETION);
221                    valid = false;
222                } else {
223                    isDefaultSet = true;
224                }
225            }
226            i++;
227        }
228        if (!phoneBoList.isEmpty() && !isDefaultSet) {
229            //this.putFieldError("dataObject."+listName+"[0].defaultValue",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
230            valid = false;
231        }
232        return valid;
233    }
234
235    /**
236     * this method validates the address object for default value
237     *
238     * @param addrBoList
239     * @param listName
240     * @return valid
241     */
242    protected boolean checkAddressMultipleDefault(List<OleEntityAddressBo> addrBoList, String listName) {
243        boolean valid = true;
244        boolean isDefaultSet = false;
245        int i = 0;
246        for (OleEntityAddressBo addr : addrBoList) {
247            EntityAddressBo entityAddressBo = addr.getEntityAddressBo();
248            if (entityAddressBo.isDefaultValue()) {
249                if (isDefaultSet) {
250                    this.putFieldError("dataObject." + listName + "[" + i + "].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_MULIT_PREFERRED_ADDRESS);
251                    valid = false;
252                } else {
253                    isDefaultSet = true;
254                }
255            }
256            i++;
257        }
258        if (!addrBoList.isEmpty() && !isDefaultSet) {
259            //this.putFieldError("dataObject."+listName+"[0].defaultValue",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
260            valid = false;
261        }
262        return valid;
263    }
264
265
266    protected boolean checkAddressMultipleDeliverAddress(List<OleEntityAddressBo> addrBoList, String listName) {
267        boolean valid = true;
268        boolean isDefaultSet = false;
269        int i = 0;
270        for (OleEntityAddressBo addr : addrBoList) {
271            OleAddressBo oleAddressBo = addr.getOleAddressBo();
272            if (oleAddressBo.isDeliverAddress()) {
273                if (isDefaultSet) {
274                    this.putFieldError("dataObject." + listName + "[" + i + "].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_MULIT_DELIVER_ADDRESS);
275                    valid = false;
276                } else {
277                    isDefaultSet = true;
278                }
279            }
280            i++;
281        }
282        if (!addrBoList.isEmpty() && !isDefaultSet) {
283            //this.putFieldError("dataObject."+listName+"[0].defaultValue",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
284            valid = false;
285        }
286        return valid;
287    }
288    /**
289     * this method validates the email object for default value
290     *
291     * @param emailBoList
292     * @param listName
293     * @return valid
294     */
295    protected boolean checkEmailMultipleDefault(List<EntityEmailBo> emailBoList, String listName) {
296        boolean valid = true;
297        boolean isDefaultSet = false;
298        int i = 0;
299        for (EntityEmailBo email : emailBoList) {
300            if (email.isDefaultValue()) {
301                if (isDefaultSet) {
302                    this.putFieldError("dataObject." + listName + "[" + i + "].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_MULIT_PREFERRED_EMAIL);
303                    valid = false;
304                } else {
305                    isDefaultSet = true;
306                }
307            }
308            i++;
309        }
310        if (!emailBoList.isEmpty() && !isDefaultSet) {
311            //this.putFieldError("dataObject."+listName+"[0].defaultValue",RiceKeyConstants.ERROR_NO_DEFAULT_SELETION);
312            valid = false;
313        }
314        return valid;
315    }
316
317    /**
318     * Gets the value of identityService property
319     *
320     * @return identityService(IdentityService)
321     */
322    public IdentityService getIdentityService() {
323        if (identityService == null) {
324            identityService = KimApiServiceLocator.getIdentityService();
325        }
326        return identityService;
327    }
328
329
330    public boolean validateAddress(OlePatronDocument olePatronDocument, String addressBos) {
331        List<OleEntityAddressBo> addressBoList = olePatronDocument.getOleEntityAddressBo();
332        OleEntityAddressBo oleEntityAddressBo;
333        boolean valid = true;
334        boolean flag=true;
335        boolean dateExist = true;
336        Map<Date,Date> map=new HashMap<>();
337        for (int i = 0; i < addressBoList.size(); i++) {
338            oleEntityAddressBo = addressBoList.get(i);
339            if (oleEntityAddressBo.getEntityAddressBo().isDefaultValue()) {
340                if (oleEntityAddressBo.getOleAddressBo().getAddressValidFrom() != null || oleEntityAddressBo.getOleAddressBo().getAddressValidTo() != null) {
341                    GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_ADDRESS_DEFAULT_DATE);
342                    flag= false;
343                }
344            }
345            if(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom()!=null && oleEntityAddressBo.getOleAddressBo().getAddressValidTo()!=null && oleEntityAddressBo.getOleAddressBo().getAddressValidFrom().compareTo(oleEntityAddressBo.getOleAddressBo().getAddressValidTo())>0){
346                GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_VALID_ADDRESS_TO_DATE);
347                flag= false;
348            }
349
350            if(!oleEntityAddressBo.getEntityAddressBo().isDefaultValue()){
351                if(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom()==null && oleEntityAddressBo.getOleAddressBo().getAddressValidTo()!=null){
352                    GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_ADDRESS_FROM_DATE, "ValidFrom");
353                    flag= false;
354                }
355                if(oleEntityAddressBo.getOleAddressBo().getAddressValidTo()==null && oleEntityAddressBo.getOleAddressBo().getAddressValidFrom()!=null){
356                    GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_ADDRESS_FROM_DATE, "ValidTo");
357                    flag= false;
358                }
359                for(Map.Entry<Date,Date> entry:map.entrySet()){
360                    if(entry.getKey()!=null&&entry.getValue()!=null&&oleEntityAddressBo.getOleAddressBo().getAddressValidFrom()!=null&&oleEntityAddressBo.getOleAddressBo().getAddressValidTo()!=null){
361                    if(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom().compareTo(entry.getKey())>=0 && oleEntityAddressBo.getOleAddressBo().getAddressValidFrom().compareTo(entry.getValue())<=0
362                            || oleEntityAddressBo.getOleAddressBo().getAddressValidTo().compareTo(entry.getKey())>=0 && oleEntityAddressBo.getOleAddressBo().getAddressValidTo().compareTo(entry.getValue())<=0){
363                        GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue",OLEConstants.OlePatron.ERROR_PATRON_ADDRESS_FROM_TO_DATE_OVERLAP);
364                        flag= false;
365                    }
366                    if(entry.getKey().compareTo(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom())>=0 && entry.getKey().compareTo(oleEntityAddressBo.getOleAddressBo().getAddressValidTo())<=0
367                            || entry.getValue().compareTo(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom())>=0 && entry.getValue().compareTo(oleEntityAddressBo.getOleAddressBo().getAddressValidTo())<=0){
368                        GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_ADDRESS_FROM_TO_DATE_OVERLAP);
369                        flag= false;
370                    }
371                    }
372                }
373            }else if (oleEntityAddressBo.getOleAddressBo().getAddressValidFrom() != null || oleEntityAddressBo.getOleAddressBo().getAddressValidTo() != null) {
374
375                if (dateExist) {
376                    dateExist = false;
377                } else {
378                    GlobalVariables.getMessageMap().putError("dataObject." + addressBos + "[0].defaultValue", OLEConstants.OlePatron.ERROR_PATRON_ADDRESS_SINGLE_DATE);
379                    flag= false;
380                }
381            }
382            map.put(oleEntityAddressBo.getOleAddressBo().getAddressValidFrom(),oleEntityAddressBo.getOleAddressBo().getAddressValidTo());
383        }
384        if(!flag){
385            return false;
386        }
387        return valid;
388    }
389
390    public boolean validateRequiredField(OlePatronDocument olePatronDocument) {
391        boolean valid = true;
392        List<OleEntityAddressBo> addressBoList = olePatronDocument.getOleEntityAddressBo();
393        List<EntityEmailBo> emailBoList = olePatronDocument.getEmails();
394        if (!(addressBoList.size() > 0 || emailBoList.size() > 0)) {
395            GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_ADDRESS);
396            valid = false;
397        }
398       /* if ( affiliationBoList.size() == 0 ) {
399            GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_AFFILIATION);
400            //this.putFieldError("dataObject.patronAffiliations",OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_AFFILIATION);
401            valid = false;
402        }
403        if ( employeeList.size() == 0 ) {
404            GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_EMPLOYEE);
405            //this.putFieldError("dataObject.employments",OLEConstants.OlePatron.ERROR_PATRON_REQUIRED_AFFILIATION);
406            valid = false;
407        }*/
408
409        return valid;
410    }
411
412    public boolean validatePatronName(OlePatronDocument olePatronDocument) {
413        boolean valid = true;
414        EntityNameBo names = olePatronDocument.getName();
415        String firstName = names.getFirstName();
416        String middleName = names.getMiddleName();
417        String lastName = names.getLastName();
418        String parameterResult = "";
419        Pattern pattern;
420        Matcher matcher;
421        boolean matchName;
422        if (firstName != null && !firstName.equals("")) {
423            parameterResult = getParameter(OLEConstants.OlePatron.PATRON_NAME_VALIDATION);
424            if (parameterResult != null) {
425                pattern = Pattern.compile(parameterResult);
426                matcher = pattern.matcher(firstName);
427                if (matcher.find()) {
428                    this.putFieldError(OLEConstants.OlePatron.FIRST_NAME, OLEConstants.OlePatron.ERROR_PATRON_FIRST_NAME);
429                    valid = false;
430                }
431            }
432        }
433        if (middleName != null && !middleName.equals("")) {
434            parameterResult = getParameter(OLEConstants.OlePatron.PATRON_NAME_VALIDATION);
435            if (parameterResult != null) {
436                pattern = Pattern.compile(parameterResult);
437                matcher = pattern.matcher(middleName);
438                if (matcher.find()) {
439                    this.putFieldError(OLEConstants.OlePatron.MIDDLE_NAME, OLEConstants.OlePatron.ERROR_PATRON_MIDDLE_NAME);
440                    valid = false;
441                }
442            }
443        }
444        if (lastName != null && !lastName.equals("")) {
445            parameterResult = getParameter(OLEConstants.OlePatron.PATRON_NAME_VALIDATION);
446            if (parameterResult != null) {
447                pattern = Pattern.compile(parameterResult);
448                matcher = pattern.matcher(lastName);
449                if (matcher.find()) {
450                    this.putFieldError(OLEConstants.OlePatron.LAST_NAME, OLEConstants.OlePatron.ERROR_PATRON_LAST_NAME);
451                    valid = false;
452                }
453            }
454        }
455        return valid;
456    }
457
458    public String getParameter(String name) {
459        ParameterKey parameterKey = ParameterKey.create(OLEConstants.APPL_ID, OLEConstants.DLVR_NMSPC, OLEConstants.DLVR_CMPNT, name);
460        Parameter parameter = CoreServiceApiServiceLocator.getParameterRepositoryService().getParameter(parameterKey);
461        return parameter != null ? parameter.getValue() : null;
462    }
463}