001    /**
002     * Copyright 2004-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.hr.time.util;
017    
018    import java.math.BigDecimal;
019    import java.sql.Date;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.commons.lang.StringUtils;
025    import org.kuali.hr.lm.LMConstants;
026    import org.kuali.hr.lm.accrual.AccrualCategory;
027    import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
028    import org.kuali.hr.lm.leavecode.LeaveCode;
029    import org.kuali.hr.lm.leaveplan.LeavePlan;
030    import org.kuali.hr.location.Location;
031    import org.kuali.hr.paygrade.PayGrade;
032    import org.kuali.hr.time.accrual.TimeOffAccrual;
033    import org.kuali.hr.time.authorization.DepartmentalRule;
034    import org.kuali.hr.time.calendar.Calendar;
035    import org.kuali.hr.time.department.Department;
036    import org.kuali.hr.time.earncode.EarnCode;
037    import org.kuali.hr.time.earncodegroup.EarnCodeGroup;
038    import org.kuali.hr.time.earncodegroup.EarnCodeGroupDefinition;
039    import org.kuali.hr.time.paytype.PayType;
040    import org.kuali.hr.time.principal.PrincipalHRAttributes;
041    import org.kuali.hr.time.salgroup.SalGroup;
042    import org.kuali.hr.time.service.base.TkServiceLocator;
043    import org.kuali.hr.time.task.Task;
044    import org.kuali.hr.time.workarea.WorkArea;
045    import org.kuali.kfs.coa.businessobject.Chart;
046    import org.kuali.rice.kim.api.identity.Person;
047    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
048    import org.kuali.rice.krad.service.KRADServiceLocator;
049    
050    /**
051     * A few methods to assist with various validation tasks.
052     */
053    public class ValidationUtils {
054    
055        /**
056         * For DepartmentalRule objects, if a work area is defined, you can not
057         * leave the department field with a wildcard. Permission for wildcarding
058         * will be checked with other methods.
059         *
060         * @param dr The DepartmentalRule to examine.
061         * @return true if valid, false otherwise.
062         */
063        public static boolean validateWorkAreaDeptWildcarding(DepartmentalRule dr) {
064            boolean ret = true;
065    
066            if (StringUtils.equals(dr.getDept(), TkConstants.WILDCARD_CHARACTER)) {
067                ret = dr.getWorkArea().equals(TkConstants.WILDCARD_LONG);
068            }
069    
070            return ret;
071        }
072    
073            /**
074             * Most basic validation: Only checks for presence in the database.
075             */
076            public static boolean validateWorkArea(Long workArea) {
077                    return validateWorkArea(workArea, null);
078            }
079    
080            /**
081             * Most basic validation: Only checks for presence in the database.
082             */
083            public static boolean validateDepartment(String department) {
084                    return validateDepartment(department, null);
085            }
086    
087            /**
088             * Most basic validation: Only checks for presence in the database.
089             */
090            public static boolean validateAccrualCategory(String accrualCategory) {
091                    return validateAccrualCategory(accrualCategory, null);
092            }
093    
094    
095            public static boolean validateSalGroup(String salGroup, Date asOfDate) {
096                    boolean valid = false;
097    
098                    if (StringUtils.equals(salGroup, TkConstants.WILDCARD_CHARACTER)) {
099                            valid = true;
100                    } else if (asOfDate != null) {
101                            SalGroup sg = TkServiceLocator.getSalGroupService().getSalGroup(salGroup, asOfDate);
102                            valid = (sg != null);
103                    } else {
104                            int count = TkServiceLocator.getSalGroupService().getSalGroupCount(salGroup);
105                            valid = (count > 0);
106                    }
107    
108                    return valid;
109            }
110    
111            public static boolean validateEarnCode(String earnCode, Date asOfDate) {
112                    boolean valid = false;
113    
114                    if (asOfDate != null) {
115                            EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
116                            valid = (ec != null);
117                    } else {
118                            int count = TkServiceLocator.getEarnCodeService().getEarnCodeCount(earnCode);
119                            valid = (count > 0);
120                    }
121    
122                    return valid;
123            }
124            
125            public static boolean validateLeaveCode(String leaveCode, Date asOfDate) {
126                    boolean valid = false;
127                    
128                    if (asOfDate != null) {
129                            LeaveCode lc = TkServiceLocator.getLeaveCodeService().getLeaveCode(leaveCode, asOfDate);
130                            valid = (lc != null);
131                    } else {
132                            Map<String, String> fieldValues = new HashMap<String, String>();
133                            fieldValues.put("leaveCode", leaveCode);
134                            int matches = KRADServiceLocator.getBusinessObjectService().countMatching(LeaveCode.class, fieldValues);
135                            
136                            valid = matches > 0;
137                    }
138                    
139                    return valid;
140            }
141            
142            public static boolean validateLeavePlan(String leavePlan, Date asOfDate) {
143                    boolean valid = false;
144                    
145                    if (asOfDate != null) {
146                            LeavePlan lp = TkServiceLocator.getLeavePlanService().getLeavePlan(leavePlan, asOfDate);
147                            valid = (lp != null);
148                    } else {
149                            // chen, moved the code that access db to service and dao
150                            valid = TkServiceLocator.getLeavePlanService().isValidLeavePlan(leavePlan);
151                    }
152                    
153                    return valid;
154            }
155    
156            public static boolean validateLeaveCode(String leaveCode, String principalId, Date asOfDate) {
157                    boolean valid = false;
158                    
159                    if (asOfDate != null) {
160                            List<LeaveCode> leaveCodes = TkServiceLocator.getLeaveCodeService().getLeaveCodes(principalId, asOfDate);
161                            if(leaveCodes != null && !leaveCodes.isEmpty()) {
162                                    for(LeaveCode leaveCodeObj : leaveCodes) {
163                                            if(leaveCodeObj.getLeaveCode() != null) {
164                                                    if(StringUtils.equals(leaveCodeObj.getLeaveCode().trim(), leaveCode.trim())){
165                                                            valid = true;
166                                                            break;
167                                                    }
168                                            }
169                                    }
170                            }
171    //                      valid = (leaveCodes != null);
172                    } else {
173                            Map<String, String> fieldValues = new HashMap<String, String>();
174                            fieldValues.put("leaveCode", leaveCode);
175                            int matches = KRADServiceLocator.getBusinessObjectService().countMatching(LeaveCode.class, fieldValues);
176                            
177                            valid = matches > 0;
178                    }
179                    
180                    return valid;
181            }
182            
183            public static boolean validateEarnCodeOfAccrualCategory(String earnCode, String accrualCategory, Date asOfDate) {
184                    boolean valid = false;
185                    
186                    if (asOfDate != null) {
187                            AccrualCategory accrualCategoryObj = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
188                            if (accrualCategoryObj != null) {
189                                    if (StringUtils.equals(earnCode, accrualCategoryObj.getEarnCode())) {
190                                            valid = true;
191                                    }
192                            }
193                    } else {
194                            Map<String, String> fieldValues = new HashMap<String, String>();
195                            fieldValues.put("earnCode", earnCode);
196                            int matches = KRADServiceLocator.getBusinessObjectService().countMatching(EarnCode.class, fieldValues);
197                            
198                            valid = matches > 0;
199                    }
200                    
201                    return valid;
202            }
203            
204            public static boolean validateAccCategory(String accrualCategory, Date asOfDate) {
205                    boolean valid = false;
206                    
207                    if (asOfDate != null) {
208                            AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
209                            valid = (ac != null);
210                    } else {
211                            Map<String, String> fieldValues = new HashMap<String, String>();
212                            fieldValues.put("accrualCategory", accrualCategory);
213                            int matches = KRADServiceLocator.getBusinessObjectService().countMatching(AccrualCategory.class, fieldValues);
214                            
215                            valid = matches > 0;
216                    }
217                    
218                    return valid;
219            }
220            
221            public static boolean validateAccCategory(String accrualCategory, String principalId, Date asOfDate) {
222                    boolean valid = false;
223                    
224                    if (asOfDate != null) {
225                            AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
226                            if(ac != null && ac.getLeavePlan() != null) {
227                                    // fetch leave plan users
228                                    if(principalId != null) {
229                                            PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
230                                            if(principalHRAttributes != null && principalHRAttributes.getLeavePlan() != null) {
231                                                    valid = StringUtils.equals(ac.getLeavePlan().trim(), principalHRAttributes.getLeavePlan().trim());
232                                            }
233                                    } else {
234                                            valid = true;
235                                    }
236                            } 
237                    } else {
238                            Map<String, String> fieldValues = new HashMap<String, String>();
239                            fieldValues.put("accrualCategory", accrualCategory);
240                            int matches = KRADServiceLocator.getBusinessObjectService().countMatching(AccrualCategory.class, fieldValues);
241                            
242                            valid = matches > 0;
243                    }
244                    return valid;
245            }
246            
247            public static boolean validateLocation(String location, Date asOfDate) {
248                    boolean valid = false;
249    
250                    if (asOfDate != null) {
251                            Location l = TkServiceLocator.getLocationService().getLocation(location, asOfDate);
252                            valid = (l != null);
253                    } else {
254                            int count = TkServiceLocator.getLocationService().getLocationCount(location);
255                            valid = (count > 0);
256                    }
257    
258                    return valid;
259            }
260    
261            public static boolean validatePayType(String payType, Date asOfDate) {
262                    boolean valid = false;
263    
264                    if (asOfDate != null) {
265                            PayType pt = TkServiceLocator.getPayTypeService().getPayType(payType, asOfDate);
266                            valid = (pt != null);
267                    } else {
268                            int count = TkServiceLocator.getPayTypeService().getPayTypeCount(payType);
269                            valid = (count > 0);
270                    }
271    
272                    return valid;
273            }
274    
275    
276            public static boolean validatePayGrade(String payGrade, Date asOfDate) {
277                    boolean valid = false;
278    
279                    if (asOfDate != null) {
280                            PayGrade pg = TkServiceLocator.getPayGradeService().getPayGrade(payGrade, asOfDate);
281                            valid = (pg != null);
282                    } else {
283                            int count = TkServiceLocator.getPayGradeService().getPayGradeCount(payGrade);
284                            valid = (count > 0);
285                    }
286    
287                    return valid;
288            }
289    
290        /**
291         *
292         * @param earnCode
293         * @param otEarnCode If true, earn code is valid ONLY if it is an overtime earn code.
294         * @param asOfDate
295         * @return
296         */
297        public static boolean validateEarnCode(String earnCode, boolean otEarnCode, Date asOfDate) {
298            boolean valid = false;
299    
300            if (asOfDate != null) {
301                EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
302                valid = (ec != null) && (otEarnCode ? ec.getOvtEarnCode().booleanValue() : true);
303            }
304    
305            return valid;
306        }
307    
308            /**
309             * Checks for row presence of a department, and optionally whether or not
310             * it is active as of the specified date.
311             */
312            public static boolean validateDepartment(String department, Date asOfDate) {
313                    boolean valid = false;
314    
315            if (StringUtils.isEmpty(department)) {
316              // do nothing, let false be returned.
317            } else if (asOfDate != null) {
318                            Department d = TkServiceLocator.getDepartmentService().getDepartment(department, asOfDate);
319                        valid = (d != null);
320                    } else {
321                            int count = TkServiceLocator.getDepartmentService().getDepartmentCount(department);
322                            valid = (count > 0);
323                    }
324    
325                    return valid;
326            }
327    
328        public static boolean validateChart(String chart) {
329            boolean valid = false;
330    
331            if (!StringUtils.isEmpty(chart)) {
332                Object o = KRADServiceLocator.getBusinessObjectService().findBySinglePrimaryKey(Chart.class, chart);
333                valid = (o instanceof Chart);
334            }
335    
336            return valid;
337        }
338    
339            /**
340             * Checks for row presence of a work area, and optionally whether or not
341             * it is active as of the specified date.
342             */
343        public static boolean validateWorkArea(Long workArea, Date asOfDate) {
344            return ValidationUtils.validateWorkArea(workArea, null, asOfDate);
345        }
346    
347            public static boolean validateWorkArea(Long workArea, String dept, Date asOfDate) {
348                    boolean valid = false;
349    
350                    if (workArea == null) {
351                            valid = false;
352                    } else if (workArea.equals(TkConstants.WILDCARD_LONG)) {
353                            valid = true;
354                    } else if (asOfDate != null) {
355                            WorkArea wa = TkServiceLocator.getWorkAreaService().getWorkArea(workArea, asOfDate);
356                if (wa != null && dept != null) {
357                    valid = StringUtils.equalsIgnoreCase(dept, wa.getDept());
358                } else {
359                                valid = (wa != null);
360                }
361                    } else {
362                // Not valid if no date is passed.
363                    }
364    
365                    return valid;
366            }
367            /**
368             * Checks for row presence of a Accrual Category, and optionally whether or not
369             * it is active as of the specified date.
370             */
371            public static boolean validateAccrualCategory(String accrualCategory, Date asOfDate) {
372                    boolean valid = false;
373    
374                    if (StringUtils.equals(accrualCategory, TkConstants.WILDCARD_CHARACTER)) {
375                            valid = true;
376                    } else if (asOfDate != null) {
377                            AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
378                            valid = (ac != null);
379                    }
380    
381                    return valid;
382            }
383    
384            /**
385             * Checks for row presence of a principal Id, and optionally whether or not
386             * it is active as of the specified date.
387             */
388            public static boolean validatePrincipalId(String principalId) {
389                    boolean valid = false;
390                    if (principalId != null) {
391                            Person p = KimApiServiceLocator.getPersonService().getPerson(principalId);
392                        valid = (p != null);
393                    }
394                    return valid;
395            }
396    
397        /**
398         * No wildcarding is accounted for in this method.
399         * @param task Task "Long Name"
400         * @param asOfDate Can be null, if we just want to look for the general case.
401         * @return True if the task is present / valid.
402         */
403        public static boolean validateTask(Long task, Date asOfDate) {
404            boolean valid = false;
405    
406            if (task != null && asOfDate != null) {
407                Task t = TkServiceLocator.getTaskService().getTask(task, asOfDate);
408                valid = (t != null);
409            } else if (task != null) {
410                    int count = TkServiceLocator.getTaskService().getTaskCount(task);
411                valid = (count > 0);
412            }
413    
414            return valid;
415        }
416    
417        /**
418         * No wildcarding is accounted for in this method.
419         * @param earnGroup EarnCodeGroup
420         * @param asOfDate Can be null, if we just want to look for the general case.
421         * @return True if the EarnCodeGroup is present / valid.
422         */
423        public static boolean validateEarnGroup(String earnGroup, Date asOfDate) {
424            boolean valid = false;
425    
426            if (earnGroup != null && asOfDate != null) {
427                EarnCodeGroup eg = TkServiceLocator.getEarnCodeGroupService().getEarnCodeGroup(earnGroup, asOfDate);
428                valid = (eg != null);
429            } else if (earnGroup != null) {
430                    int count = TkServiceLocator.getEarnCodeGroupService().getEarnCodeGroupCount(earnGroup);
431                valid = (count > 0);
432            }
433    
434            return valid;
435        }
436        
437        /**
438         * @param earnGroup EarnCodeGroup
439         * @param asOfDate
440         * @return True if the EarnCodeGroup has overtime earn codes
441         */
442        public static boolean earnGroupHasOvertimeEarnCodes(String earnGroup, Date asOfDate) {
443             if (earnGroup != null && asOfDate != null) {
444                 EarnCodeGroup eg = TkServiceLocator.getEarnCodeGroupService().getEarnCodeGroup(earnGroup, asOfDate);
445                 if(eg != null) {
446                    for(EarnCodeGroupDefinition egd : eg.getEarnCodeGroups()) {
447                            if(egd.getEarnCode() != null) {
448                                    EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(egd.getEarnCode(), asOfDate);
449                                    if(ec != null && ec.getOvtEarnCode()) {
450                                            return true;
451                                    }
452                            }
453                    }
454                 }
455             }
456    
457            return false;
458        }
459    
460    
461            /**
462             * Checks for row presence of a pay calendar
463             */
464            public static boolean validateCalendar(String calendarName) {
465                    Map<String, String> fieldValues = new HashMap<String, String>();
466                    fieldValues.put("calendarName", calendarName);
467                    int matches = KRADServiceLocator.getBusinessObjectService().countMatching(Calendar.class, fieldValues);
468    
469            return matches > 0;
470            }
471    
472       public static boolean duplicateDeptEarnCodeExists(EarnCodeSecurity deptEarnCode) {
473               boolean valid = false;
474               int count = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurityCount
475                   (deptEarnCode.getDept(), deptEarnCode.getHrSalGroup(), deptEarnCode.getEarnCode(), deptEarnCode.isEmployee() ? "1" : "0",
476                           deptEarnCode.isApprover() ? "1" : "0", deptEarnCode.getLocation(), deptEarnCode.isActive() ? "Y" : "N", deptEarnCode.getEffectiveDate(), null);
477           if(count == 1) {
478               valid = true;
479               count = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurityCount
480                       (deptEarnCode.getDept(), deptEarnCode.getHrSalGroup(), deptEarnCode.getEarnCode(), deptEarnCode.isEmployee() ? "1" : "0",
481                               deptEarnCode.isApprover() ? "1" : "0", deptEarnCode.getLocation(), deptEarnCode.isActive() ? "Y" : "N", deptEarnCode.getEffectiveDate(), deptEarnCode.getHrEarnCodeSecurityId());
482               if(count == 1) {
483                       valid = false;
484               }
485           } else if(count > 1) {
486               valid = true;
487           }
488    
489               return valid;
490       }
491       
492       public static boolean duplicateTimeOffAccrual (TimeOffAccrual timeOffAccrual) {
493               boolean valid = false;
494               int count = TkServiceLocator.getTimeOffAccrualService().getTimeOffAccrualCount
495                   (timeOffAccrual.getAccrualCategory(), timeOffAccrual.getEffectiveDate(), timeOffAccrual.getPrincipalId(), null);
496               if(count == 1) {
497               valid = true;
498               count = TkServiceLocator.getTimeOffAccrualService().getTimeOffAccrualCount
499                       (timeOffAccrual.getAccrualCategory(), timeOffAccrual.getEffectiveDate(), timeOffAccrual.getPrincipalId(), timeOffAccrual.getLmAccrualId());
500               if(count == 1) {
501                       valid = false;
502               }
503           } else if(count > 1) {
504               valid = true;
505           }
506               return valid;
507       }
508    
509       /**
510        * Checks for date not more than one year in the future from accrualDAte
511        * 
512        */
513    
514       public static boolean validateOneYearFutureDateFromAccrualDate(Date date, Date accrualDate){
515               java.util.Calendar startDate = java.util.Calendar.getInstance();
516               startDate.setTime(accrualDate);
517               startDate.add(java.util.Calendar.DATE, -1);
518               startDate.set(java.util.Calendar.SECOND, 0);
519               startDate.set(java.util.Calendar.MINUTE, 0);
520               startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
521               java.util.Calendar endDate = java.util.Calendar.getInstance();
522               endDate.setTime(accrualDate);
523               endDate.add(java.util.Calendar.YEAR, 1); // One year after the current date
524               return date.compareTo(startDate.getTime()) * date.compareTo(endDate.getTime()) <= 0;
525       }
526       
527       
528       /**
529        * Checks for date not more than one year in the future or current date
530        * 
531        */
532    
533       public static boolean validateOneYearFutureDate(Date date){
534               java.util.Calendar startDate = java.util.Calendar.getInstance();
535               startDate.add(java.util.Calendar.DATE, -1);
536               startDate.set(java.util.Calendar.SECOND, 0);
537               startDate.set(java.util.Calendar.MINUTE, 0);
538               startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
539               java.util.Calendar endDate = java.util.Calendar.getInstance();
540               endDate.add(java.util.Calendar.YEAR, 1); // One year after the current date
541               return date.compareTo(startDate.getTime()) * date.compareTo(endDate.getTime()) <= 0;
542       }
543       
544       /**
545        * Checks for date not more than one year in the future and does not consider past date
546        * 
547        */
548    
549       public static boolean validateOneYearFutureEffectiveDate(Date date){
550               java.util.Calendar startDate = java.util.Calendar.getInstance();
551               startDate.set(java.util.Calendar.MILLISECOND, 0);
552               startDate.set(java.util.Calendar.SECOND, 0);
553               startDate.set(java.util.Calendar.MINUTE, 0);
554               startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
555               startDate.add(java.util.Calendar.YEAR, 1); // One year after the current date
556               return date.compareTo(startDate.getTime()) <= 0;
557       }
558       
559       /**
560        * Checks for date in the future
561        * 
562        */
563       
564       public static boolean validateFutureDate(Date date){
565               java.util.Calendar startDate = java.util.Calendar.getInstance();
566               startDate.add(java.util.Calendar.DATE, 0);
567               startDate.set(java.util.Calendar.SECOND, 0);
568               startDate.set(java.util.Calendar.MINUTE, 0);
569               startDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
570               return date.compareTo(startDate.getTime()) > 0;
571       }
572    
573            /**
574             * Checks for row presence of a pay calendar by calendar type
575             */
576            public static boolean validateCalendarByType(String calendarName, String calendarType) {
577                    Map<String, String> fieldValues = new HashMap<String, String>();
578                    fieldValues.put("calendarName", calendarName);
579                    fieldValues.put("calendarTypes", calendarType);
580                    int matches = KRADServiceLocator.getBusinessObjectService().countMatching(Calendar.class, fieldValues);
581                    
582                    return matches > 0;
583            }
584            
585            public static boolean validateRecordMethod(String recordMethod, String accrualCategory, Date asOfDate) {
586                    boolean valid = false;
587                    if (asOfDate != null) {
588                            AccrualCategory ac = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(accrualCategory, asOfDate);
589                            if (ac != null
590                        && ac.getUnitOfTime() != null) {
591                    if (LMConstants.RECORD_METHOD.HOUR.equals(ac.getUnitOfTime())
592                            && (LMConstants.RECORD_METHOD.HOUR.equals(recordMethod))
593                                || LMConstants.RECORD_METHOD.TIME.equals(recordMethod)) {
594                        valid = true;
595                    } else {
596                        valid = StringUtils.equalsIgnoreCase(ac.getUnitOfTime(), recordMethod);
597                    }
598    
599                }
600                    }
601                    return valid;
602            }
603            
604            public static boolean validateEarnCodeFraction(String earnCode, BigDecimal amount, Date asOfDate) {
605                    boolean valid = true;
606                     EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
607                     if(ec != null && ec.getFractionalTimeAllowed() != null) {
608                             BigDecimal fracAllowed = new BigDecimal(ec.getFractionalTimeAllowed());
609                             if(amount.scale() > fracAllowed.scale()) {
610                                     valid = false;
611                             }
612                     }
613                    return valid;
614            }
615    }