diff --git a/.gitignore b/.gitignore index 6a93dffa5f3..3de41031d36 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ hrjob/build bin/setup.conf hrabsence/build /nbproject/private/ +core-fork-last-commit-patched.txt # Exclude sass cache from all extension directories */.sass-cache/ diff --git a/Jenkinsfile b/Jenkinsfile index 31be1839ff0..61cc6457c07 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -23,7 +23,7 @@ pipeline { stages { stage('Pre-tasks execution') { steps { - sendBuildStartdNotification() + sendBuildStartNotification() // Print all Environment variables sh 'printenv | sort' @@ -189,26 +189,34 @@ pipeline { /* * Sends a notification when the build starts */ -def sendBuildStartdNotification() { - def message = 'Building ' + getBuildTargetLink() + '. ' + getReportLink() +def sendBuildStartNotification() { + def msgHipChat = 'Building ' + getBuildTargetLink('hipchat') + '. ' + getReportLink('hipchat') + def msgSlack = 'Building ' + getBuildTargetLink('slack') + '. ' + getReportLink('slack') - sendHipchatNotification('YELLOW', message) + sendHipchatNotification('YELLOW', msgHipChat) + sendSlackNotification('warning', msgSlack) } /* * Sends a notification when the build is completed successfully */ def sendBuildSuccessNotification() { - def message = getBuildTargetLink() + ' built successfully. Time: $BUILD_DURATION. ' + getReportLink() - sendHipchatNotification('GREEN', message) + def msgHipChat = getBuildTargetLink('hipchat') + ' built successfully. Time: $BUILD_DURATION. ' + getReportLink('hipchat') + def msgSlack = getBuildTargetLink('slack') + ' built successfully. Time: ' + getBuildDuration(currentBuild) + '. ' + getReportLink('slack') + + sendHipchatNotification('GREEN', msgHipChat) + sendSlackNotification('good', msgSlack) } /* * Sends a notification when the build fails */ def sendBuildFailureNotification() { - def message = 'Failed to build ' + getBuildTargetLink() + '. Time: $BUILD_DURATION. No. of failed tests: ${TEST_COUNTS,var=\"fail\"}. ' + getReportLink() - sendHipchatNotification('RED', message) + def msgHipChat = 'Failed to build ' + getBuildTargetLink('hipchat') + '. Time: $BUILD_DURATION. No. of failed tests: ${TEST_COUNTS,var=\"fail\"}. ' + getReportLink('hipchat') + def msgSlack = 'Failed to build ' + getBuildTargetLink('slack') + '. Time: ' + getBuildDuration(currentBuild) + '. ' + getReportLink('slack') + + sendHipchatNotification('RED', msgHipChat) + sendSlackNotification('danger', msgSlack) } /* @@ -218,16 +226,38 @@ def sendHipchatNotification(String color, String message) { hipchatSend color: color, message: message, notify: true } +/* + * Sends a notification to Slack + */ +def sendSlackNotification(String color, String message) { + slackSend color: color, message: message, notify: true +} + +/* + * Returns the build duration without the "and counting" suffix + */ +def getBuildDuration(build) { + return build.durationString.replace(' and counting', '') +} + /* * Returns a link to what is being built. If it's a PR, then it's a link to the pull request itself. * If it's a branch, then it's a link in the format http://github.com/org/repo/tree/branch */ -def getBuildTargetLink() { - if(buildIsForAPullRequest()) { - return "\"${env.CHANGE_TITLE}\"" +def getBuildTargetLink(String client) { + def link = '' + def forPR = buildIsForAPullRequest() + + switch (client) { + case 'hipchat': + link = forPR ? "\"${env.CHANGE_TITLE}\"" : '"' + env.BRANCH_NAME + '"' + break; + case 'slack': + link = forPR ? "<${env.CHANGE_URL}|${env.CHANGE_TITLE}>" : '<' + getRepositoryUrlForBuildBranch() + '|' + env.BRANCH_NAME + '>' + break; } - return '"' + env.BRANCH_NAME + '"' + return link } /* @@ -250,8 +280,19 @@ def getRepositoryUrlForBuildBranch() { /* * Returns the Blue Ocean build report URL for the current job */ -def getReportLink() { - return 'Click here to see the build report' +def getReportLink(String client) { + def link = '' + + switch (client) { + case 'hipchat': + link = 'Click here to see the build report' + break + case 'slack': + link = "Click <${env.RUN_DISPLAY_URL}|here> to see the build report" + break + } + + return link } def cloneCiviHRRepositories(String envBranch) { diff --git a/bin/apply-core-fork-patch.sh b/bin/apply-core-fork-patch.sh new file mode 100755 index 00000000000..17889610737 --- /dev/null +++ b/bin/apply-core-fork-patch.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +set -e + +API_URL_BASE="https://api.github.com/repos/compucorp/civicrm-core" +LAST_COMMIT_PATCHED_FILE="core-fork-last-commit-patched.txt" +PATCH_FILE="fork-patch.diff" + +civiRoot="" + +####################################### +# Applies the patch on the core files +# +# Globals: +# $civiRoot +# $PATCH_FILE +# Arguments: +# None +# Returns: +# None +####################################### +applyPatch () { + (cd "$civiRoot" && patch -p1 < "$PATCH_FILE" >> /dev/null) +} + +####################################### +# Creates a diff patch file by sending a request to the given GitHub API url +# +# Globals: +# $API_URL_BASE +# $civiRoot +# $PATCH_FILE +# Arguments: +# $1 base commit of the comparison +# $2 head commit of the comparison +# Returns: +# None +####################################### +createPatch () { + curl "$API_URL_BASE/compare/$1...$2" -s -H "Accept: application/vnd.github.v3.diff" > "$civiRoot/$PATCH_FILE" +} + +####################################### +# Programmatically gets the current CiviCRM version +# +# Globals: +# None +# Arguments: +# None +# Returns: +# String +####################################### +getCiviVersion () { + drush eval "civicrm_initialize(); echo CRM_Utils_System::version();" +} + +####################################### +# Uses Python to read the property's value of a JSON file +# +# Globals: +# None +# Arguments: +# $1 JSON file +# $2 property name +# Returns: +# String +####################################### +JSONValue () { + python -c "import sys, json; print json.load(sys.stdin)['$2']" < "$1" +} + +####################################### +# Returns the civicrm root path +# +# Globals: +# None +# Arguments: +# None +# Returns: +# String +####################################### +setCivicrmRootPath () { + civiRoot=$(drush eval "civicrm_initialize(); echo \\Civi::paths()->getPath('[civicrm.root]/.')") +} + +####################################### +# Updates the reference, in the LAST_COMMIT_PATCHED_FILE, to the last commit +# patched onto the core files +# +# Globals: +# $civiRoot +# $LAST_COMMIT_PATCHED_FILE +# Arguments: +# None +# Returns: +# None +####################################### +updateLastCommitPatched () { + # It uses the same file as temporary recipient of the full commit data + curl "$API_URL_BASE/commits/$1" -s > "$LAST_COMMIT_PATCHED_FILE" + sha=$(JSONValue "$LAST_COMMIT_PATCHED_FILE" "sha") + + echo "$sha" > "$LAST_COMMIT_PATCHED_FILE" +} + +# --------------- + +touch -a $LAST_COMMIT_PATCHED_FILE +setCivicrmRootPath + +civiVersion=$(getCiviVersion) +lastCommitPatched=$(cat "$LAST_COMMIT_PATCHED_FILE") +patchesBranch="$civiVersion-patches" +[ ! -z "$lastCommitPatched" ] && baseHead=$lastCommitPatched || baseHead=$civiVersion + +echo "Fetching compucorp:civicrm-core patch..." +createPatch "$baseHead" "$patchesBranch" + +if [ -s "$civiRoot/$PATCH_FILE" ]; then + echo "Applying compucorp:civicrm-core patch..." + applyPatch + + echo "Updating reference to SHA of last commit patched..." + updateLastCommitPatched "$patchesBranch" + + echo "Patch applied" +else + echo "Patch was empty, no diffs found" +fi + +rm "$civiRoot/$PATCH_FILE" diff --git a/com.civicrm.hrjobroles/CRM/Hrjobroles/Upgrader.php b/com.civicrm.hrjobroles/CRM/Hrjobroles/Upgrader.php index 372818cfdad..3e58b5465f2 100644 --- a/com.civicrm.hrjobroles/CRM/Hrjobroles/Upgrader.php +++ b/com.civicrm.hrjobroles/CRM/Hrjobroles/Upgrader.php @@ -45,6 +45,70 @@ public function upgrade_1004() { return TRUE; } + /** + * Adds a submenu containing links to edit job role option groups + * + * @return bool + */ + public function upgrade_1005() { + $domain = CRM_Core_Config::domainID(); + $params = ['return' => 'id', 'name' => 'Administer', 'domain_id' => $domain]; + $administerId = (int) civicrm_api3('Navigation', 'getvalue', $params); + + $permission = 'access CiviCRM'; + $parent = $this->createNavItem('Job Roles', $permission, $administerId); + $parentId = $parent['id']; + + // Weight cannot be set when creating for the first time + civicrm_api3('Navigation', 'create', ['id' => $parentId, 'weight' => -99]); + + // If we don't flush it will not recognize newly created parent_id + CRM_Core_PseudoConstant::flush(); + + $optionGroupLinks = [ + 'Locations' => 'hrjc_location', + 'Regions' => 'hrjc_region', + 'Departments' => 'hrjc_department', + 'Levels' => 'hrjc_level_type', + 'Cost Centres' => 'cost_centres', + ]; + + foreach ($optionGroupLinks as $itemName => $optionGroup) { + $link = 'civicrm/admin/options/' . $optionGroup . '?reset=1'; + $this->createNavItem($itemName, $permission, $parentId, ['url' => $link]); + } + + return TRUE; + } + + /** + * Creates a navigation menu item using the API + * + * @param string $name + * @param string $permission + * @param int $parentID + * @param array $params + * + * @return array + */ + private function createNavItem($name, $permission, $parentID, $params = []) { + $params = array_merge([ + 'name' => $name, + 'label' => ts($name), + 'permission' => $permission, + 'parent_id' => $parentID, + 'is_active' => 1, + ], $params); + + $existing = civicrm_api3('Navigation', 'get', $params); + + if ($existing['count'] > 0) { + return array_shift($existing['values']); + } + + return civicrm_api3('Navigation', 'create', $params); + } + /** * Creates new Option Group for Cost Centres */ diff --git a/com.civicrm.hrjobroles/info.xml b/com.civicrm.hrjobroles/info.xml index 3f08b059f5a..869358d8eee 100644 --- a/com.civicrm.hrjobroles/info.xml +++ b/com.civicrm.hrjobroles/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/com.civicrm.hrjobroles/js/dist/job-roles.min.js b/com.civicrm.hrjobroles/js/dist/job-roles.min.js index 56a4735f0ef..6f010dec8c6 100644 --- a/com.civicrm.hrjobroles/js/dist/job-roles.min.js +++ b/com.civicrm.hrjobroles/js/dist/job-roles.min.js @@ -12,6 +12,6 @@ Build date: 2014-01-10 */ -define("job-roles/modules/job-roles.config",["common/angular"],function(e){"use strict";function t(e,t,n,r,a){t.debugEnabled(a.debug),r.resolveForAll({format:["DateFormat",function(e){return e.getDateFormat()}]}).when("/",{templateUrl:a.pathBaseUrl+a.pathTpl+"mainTemplate.html?v=1",resolve:{},controller:"JobRolesController",controllerAs:"jobroles"}).otherwise({redirectTo:"/"}),n.defaults.stripTrailingSlashes=!1,e.defaults.headers.common["X-Requested-With"]="XMLHttpRequest"}e.module("hrjobroles.config",["hrjobroles.constants"]).config(t),t.$inject=["$httpProvider","$logProvider","$resourceProvider","$routeProvider","settings"]}),define("job-roles/modules/job-roles.constants",["common/angular"],function(e){"use strict";e.module("hrjobroles.constants",[]).constant("settings",{classNamePrefix:"hrjobroles-",contactId:decodeURIComponent((new RegExp("[?|&]cid=([^&;]+?)(&|#|;|$)").exec(location.search)||[null,""])[1].replace(/\+/g,"%20"))||null,debug:!0,pathApp:CRM.vars.hrjobroles.path,pathRest:CRM.url("civicrm/ajax/rest"),pathBaseUrl:CRM.vars.hrjobroles.baseURL+"/",pathTpl:"views/",pathIncludeTpl:"views/include/"})}),define("job-roles/controllers/job-roles.controller",["common/angular","common/lodash","common/moment"],function(e,t,n){"use strict";function r(r,a,o,i,s,l,u,c,d,f,m,p,b,h,v,g){function _(e,t){void 0===ye.editData[e]&&(ye.editData[e]={}),"cost_centre"===t?(void 0!==ye.editData[e].cost_centers&&ye.editData[e].cost_centers instanceof Array||(ye.editData[e].cost_centers=[]),ye.editData[e].cost_centers.push({id:ye.editData[e].cost_centers.length+1,cost_centre_id:"",type:"1",percentage:"0",amount:"0"})):(void 0!==ye.editData[e].funders&&ye.editData[e].funders instanceof Array||(ye.editData[e].funders=[]),ye.editData[e].funders.push({id:ye.editData[e].funders.length+1,funder_id:"",type:"1",percentage:"0",amount:"0"}))}function $(){ye.add_new=!0}function w(){ye.add_new=!1,delete ye.editData.new_role_id}function y(e,t){ye.viewTab[e]=t}function D(t,n){P(t)&&(t=null),P(n)&&(n=null);var r=!0;return!!t&&(e.forEach(ye.contractsData,function(e){ge(t)===ge(e.start_date)&&ge(n)===ge(e.end_date)&&(r=!1)}),r)}function E(){return void 0===ye.editData.new_role_id||void 0===ye.editData.new_role_id.title||""===ye.editData.new_role_id.title||void 0===ye.editData.new_role_id.job_contract_id||""===ye.editData.new_role_id.job_contract_id}function j(e){ye.collapsedRows[e]=!ye.collapsedRows[e]}function C(e){return v.getContracts(e).then(function(e){for(var t=[],n={},r=0;r-1&&t.start.push(e),r.indexOf("end_date")>-1&&t.end.push(e)}),b.validate(e.start,e.end,e.contractStart,e.contractEnd),0===n}function he(e){e.start_date.$error.custom=[],e.end_date.$error.custom=[];var t=J(e.contract.$viewValue);return void 0===t?"Contract is missing":!!be({start:e.start_date.$viewValue,end:e.end_date.$viewValue,contractStart:t.start_date,contractEnd:t.end_date},{start:e.start_date.$error.custom,end:e.end_date.$error.custom})||"Error"}function ve(e){if("title"===e||" "===e)return"Title cannot be title!"}a.debug("Controller: JobRolesController");var ge=r("formatDate"),_e={},$e=r("getActiveValues"),we=["funders","cost_centers"],ye=this;ye.contactId=m.contactId,ye.format=p.DATE_FORMAT,ye.loading=!0,ye.pastJobRoles=[],ye.presentJobRoles=[],ye.collapsedRows=[],ye.contactList=[],ye.editData={},ye.viewTab=[],ye.CalendarShow=[],ye.contractsData=[],ye.DepartmentsData={},ye.LevelsData={},ye.LocationsData={},ye.RegionsData={},ye.addNewRoleUrl=m.pathBaseUrl+m.pathIncludeTpl+"add_new_role.html",ye.jobRolePanelUrl=m.pathBaseUrl+m.pathIncludeTpl+"job_role_panel.html",ye.rowTypes={},ye.rowTypes[0]={id:0,name:"Fixed"},ye.rowTypes[1]={id:1,name:"%"},ye.addAdditionalRow=_,ye.addNewRole=$,ye.cancelNewRole=w,ye.changeTab=y,ye.checkIfDatesAreCustom=D,ye.checkNewRole=E,ye.collapseRow=j,ye.deleteAdditionalRow=F,ye.dpOpen=A,ye.getContactList=k,ye.getCostLabel=L,ye.initData=B,ye.isChanged=H,ye.isOpen=V,ye.isRowCollapsed=Y,ye.isTab=G,ye.onAfterSave=K,ye.onCancel=Z,ye.onContractEdited=X,ye.onContractSelected=Q,ye.open=ee,ye.removeRole=ne,ye.saveNewRole=re,ye.select=ae,ye.showRowType=oe,ye.showSave=ie,ye.status="",ye.today=le,ye.updateAdditionalRowType=ue,ye.updateRole=me,ye.validateRole=he,ye.validateTitle=ve,function(){se(),ye.today(),o.all([I(),M(ye.contactId),ye.getContactList()]).then(function(){ye.loading=!1})}()}return r.__name="JobRolesController",r.$inject=["$filter","$log","$q","$rootElement","$route","$routeParams","$scope","$timeout","$uibModal","DOMEventTrigger","settings","HR_settings","dateValidation","filtersService","jobRoleService","pubSub"],r}),define("job-roles/controllers/modal-dialog.controller",[],function(){"use strict";function e(e,t,n,r){function a(){e.dismiss("Cancel")}function o(t){e.close(t||!0)}t.debug("Controller: ModalDialogController");var i=this;i.copyCancel=r.copyCancel||"Cancel",i.copyConfirm=r.copyConfirm||"Yes",i.msg=r.msg||"",i.title=r.title||"CiviHR Job Roles",i.cancel=a,i.confirm=o}return e.__name="ModalDialogController",e.$inject=["$uibModalInstance","$log","$timeout","content"],e}),define("job-roles/modules/job-roles.controllers",["common/angular","job-roles/controllers/job-roles.controller","job-roles/controllers/modal-dialog.controller"],function(e,t,n){"use strict";return e.module("hrjobroles.controllers",[]).controller(t.__name,t).controller(n.__name,n)}),angular.module("xeditable",[]).value("editableOptions",{theme:"default",buttons:"right",blurElem:"cancel",blurForm:"ignore",activate:"focus"}),angular.module("xeditable").directive("editableBsdate",["editableDirectiveFactory",function(e){return e({directiveName:"editableBsdate",inputTpl:''})}]),angular.module("xeditable").directive("editableBstime",["editableDirectiveFactory",function(e){return e({directiveName:"editableBstime",inputTpl:"",render:function(){this.parent.render.call(this);var e=angular.element('
');e.attr("ng-model",this.inputEl.attr("ng-model")),this.inputEl.removeAttr("ng-model"),this.attrs.eNgChange&&(e.attr("ng-change",this.inputEl.attr("ng-change")),this.inputEl.removeAttr("ng-change")),this.inputEl.wrap(e)}})}]),angular.module("xeditable").directive("editableCheckbox",["editableDirectiveFactory",function(e){return e({directiveName:"editableCheckbox",inputTpl:'',render:function(){this.parent.render.call(this),this.attrs.eTitle&&(this.inputEl.wrap(""),this.inputEl.after(angular.element("").text(this.attrs.eTitle)))},autosubmit:function(){var e=this;e.inputEl.bind("change",function(){setTimeout(function(){e.scope.$apply(function(){e.scope.$form.$submit()})},500)})}})}]),angular.module("xeditable").directive("editableChecklist",["editableDirectiveFactory","editableNgOptionsParser",function(e,t){return e({directiveName:"editableChecklist",inputTpl:"",useCopy:!0,render:function(){this.parent.render.call(this);var e=t(this.attrs.eNgOptions),n='';this.inputEl.removeAttr("ng-model"),this.inputEl.removeAttr("ng-options"),this.inputEl.html(n)}})}]),function(){var e="text|email|tel|number|url|search|color|date|datetime|time|month|week".split("|");angular.forEach(e,function(e){var t="editable"+e.charAt(0).toUpperCase()+e.slice(1);angular.module("xeditable").directive(t,["editableDirectiveFactory",function(n){return n({directiveName:t,inputTpl:''})}])}),angular.module("xeditable").directive("editableRange",["editableDirectiveFactory",function(e){return e({directiveName:"editableRange",inputTpl:'',render:function(){this.parent.render.call(this),this.inputEl.after("{{$data}}")}})}])}(),angular.module("xeditable").directive("editableRadiolist",["editableDirectiveFactory","editableNgOptionsParser",function(e,t){return e({directiveName:"editableRadiolist",inputTpl:"",render:function(){this.parent.render.call(this);var e=t(this.attrs.eNgOptions),n='';this.inputEl.removeAttr("ng-model"),this.inputEl.removeAttr("ng-options"),this.inputEl.html(n)},autosubmit:function(){var e=this;e.inputEl.bind("change",function(){setTimeout(function(){e.scope.$apply(function(){e.scope.$form.$submit()})},500)})}})}]),angular.module("xeditable").directive("editableSelect",["editableDirectiveFactory",function(e){return e({directiveName:"editableSelect",inputTpl:"",autosubmit:function(){var e=this;e.inputEl.bind("change",function(){e.scope.$apply(function(){e.scope.$form.$submit()})})}})}]),angular.module("xeditable").directive("editableTextarea",["editableDirectiveFactory",function(e){return e({directiveName:"editableTextarea",inputTpl:"",addListeners:function(){var e=this;e.parent.addListeners.call(e),e.single&&"no"!==e.buttons&&e.autosubmit()},autosubmit:function(){var e=this;e.inputEl.bind("keydown",function(t){(t.ctrlKey||t.metaKey)&&13===t.keyCode&&e.scope.$apply(function(){e.scope.$form.$submit()})})}})}]),angular.module("xeditable").factory("editableController",["$q","editableUtils",function(e,t){function n(e,n,r,a,o,i,s,l,u){var c,d,f=this;f.scope=e,f.elem=r,f.attrs=n,f.inputEl=null,f.editorEl=null,f.single=!0,f.error="",f.theme=o[i.theme]||o.default,f.parent={},f.inputTpl="",f.directiveName="",f.useCopy=!1,f.single=null,f.buttons="right",f.init=function(t){if(f.single=t,f.name=n.eName||n[f.directiveName],!n[f.directiveName])throw"You should provide value for `"+f.directiveName+"` in editable element!";c=a(n[f.directiveName]),f.buttons=f.single?f.attrs.buttons||i.buttons:"no",n.eName&&f.scope.$watch("$data",function(e){f.scope.$form.$data[n.eName]=e}),n.onshow&&(f.onshow=function(){return f.catchError(a(n.onshow)(e))}),n.onhide&&(f.onhide=function(){return a(n.onhide)(e)}),n.oncancel&&(f.oncancel=function(){return a(n.oncancel)(e)}),n.onbeforesave&&(f.onbeforesave=function(){return f.catchError(a(n.onbeforesave)(e))}),n.onaftersave&&(f.onaftersave=function(){return f.catchError(a(n.onaftersave)(e))}),e.$parent.$watch(n[f.directiveName],function(){f.handleEmpty()})},f.render=function(){var e=f.theme;f.inputEl=angular.element(f.inputTpl),f.controlsEl=angular.element(e.controlsTpl),f.controlsEl.append(f.inputEl),"no"!==f.buttons&&(f.buttonsEl=angular.element(e.buttonsTpl),f.submitEl=angular.element(e.submitTpl),f.cancelEl=angular.element(e.cancelTpl),f.buttonsEl.append(f.submitEl).append(f.cancelEl),f.controlsEl.append(f.buttonsEl),f.inputEl.addClass("editable-has-buttons")),f.errorEl=angular.element(e.errorTpl),f.controlsEl.append(f.errorEl),f.editorEl=angular.element(f.single?e.formTpl:e.noformTpl),f.editorEl.append(f.controlsEl);for(var r in n.$attr)if(!(r.length<=1)){var a=!1,o=r.substring(1,2);if("e"===r.substring(0,1)&&o===o.toUpperCase()&&"Form"!==(a=r.substring(1))&&"NgSubmit"!==a){a=a.substring(0,1).toLowerCase()+t.camelToDash(a.substring(1));var s=""===n[r]?a:n[r];f.inputEl.attr(a,s)}}f.inputEl.addClass("editable-input"),f.inputEl.attr("ng-model","$data"),f.editorEl.addClass(t.camelToDash(f.directiveName)),f.single&&(f.editorEl.attr("editable-form","$form"),f.editorEl.attr("blur",f.attrs.blur||("no"===f.buttons?"cancel":i.blurElem))),angular.isFunction(e.postrender)&&e.postrender.call(f)},f.setLocalValue=function(){f.scope.$data=f.useCopy?angular.copy(c(e.$parent)):c(e.$parent)},f.show=function(){return f.setLocalValue(),f.render(),r.after(f.editorEl),l(f.editorEl)(e),f.addListeners(),r.addClass("editable-hide"),f.onshow()},f.hide=function(){return f.editorEl.remove(),r.removeClass("editable-hide"),f.onhide()},f.cancel=function(){f.oncancel()},f.addListeners=function(){f.inputEl.bind("keyup",function(e){if(f.single)switch(e.keyCode){case 27:f.scope.$apply(function(){f.scope.$form.$cancel()})}}),f.single&&"no"===f.buttons&&f.autosubmit(),f.editorEl.bind("click",function(e){1===e.which&&f.scope.$form.$visible&&(f.scope.$form._clicked=!0)})},f.setWaiting=function(e){e?(d=!f.inputEl.attr("disabled")&&!f.inputEl.attr("ng-disabled")&&!f.inputEl.attr("ng-enabled"))&&(f.inputEl.attr("disabled","disabled"),f.buttonsEl&&f.buttonsEl.find("button").attr("disabled","disabled")):d&&(f.inputEl.removeAttr("disabled"),f.buttonsEl&&f.buttonsEl.find("button").removeAttr("disabled"))},f.activate=function(){setTimeout(function(){var e=f.inputEl[0];"focus"===i.activate&&e.focus&&e.focus(),"select"===i.activate&&e.select&&e.select()},0)},f.setError=function(t){angular.isObject(t)||(e.$error=t,f.error=t)},f.catchError=function(e,t){return angular.isObject(e)&&!0!==t?u.when(e).then(angular.bind(this,function(e){this.catchError(e,!0)}),angular.bind(this,function(e){this.catchError(e,!0)})):t&&angular.isObject(e)&&e.status&&200!==e.status&&e.data&&angular.isString(e.data)?(this.setError(e.data),e=e.data):angular.isString(e)&&this.setError(e),e},f.save=function(){c.assign(e.$parent,angular.copy(f.scope.$data))},f.handleEmpty=function(){var t=c(e.$parent),n=null===t||void 0===t||""===t||angular.isArray(t)&&0===t.length;r.toggleClass("editable-empty",n)},f.autosubmit=angular.noop,f.onshow=angular.noop,f.onhide=angular.noop,f.oncancel=angular.noop,f.onbeforesave=angular.noop,f.onaftersave=angular.noop}return n.$inject=["$scope","$attrs","$element","$parse","editableThemes","editableOptions","$rootScope","$compile","$q"],n}]),angular.module("xeditable").factory("editableDirectiveFactory",["$parse","$compile","editableThemes","$rootScope","$document","editableController","editableFormController",function(e,t,n,r,a,o,i){return function(t){return{restrict:"A",scope:!0,require:[t.directiveName,"?^form"],controller:o,link:function(n,o,s,l){var u,c=l[0],d=!1;if(l[1])u=l[1],d=!0;else if(s.eForm){var f=e(s.eForm)(n);if(f)u=f,d=!0;else for(var m=0;m=0&&e.splice(n,1),t},camelToDash:function(e){var t=/[A-Z]/g;return e.replace(t,function(e,t){return(t?"-":"")+e.toLowerCase()})},dashToCamel:function(e){var t=/([\:\-\_]+(.))/g,n=/^moz([A-Z])/;return e.replace(t,function(e,t,n,r){return r?n.toUpperCase():n}).replace(n,"Moz$1")}}}]),angular.module("xeditable").factory("editableNgOptionsParser",[function(){function e(e){var n;if(!(n=e.match(t)))throw"ng-options parse error";var r,a=n[2]||n[1],o=n[4]||n[6],i=n[5],s=(n[3],n[2]?n[1]:o),l=n[7],u=n[8],c=u?n[8]:null;return void 0===i?(r=o+" in "+l,void 0!==u&&(r+=" track by "+c)):r="("+i+", "+o+") in "+l,{ngRepeat:r,locals:{valueName:o,keyName:i,valueFn:s,displayFn:a}}}var t=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;return e}]),angular.module("xeditable").factory("editableThemes",function(){return{default:{formTpl:'
',noformTpl:'',controlsTpl:'',inputTpl:"",errorTpl:'
',buttonsTpl:'',submitTpl:'',cancelTpl:''},bs2:{formTpl:'
',noformTpl:'',controlsTpl:'
',inputTpl:"",errorTpl:'
',buttonsTpl:'',submitTpl:'',cancelTpl:''},bs3:{formTpl:'
', -noformTpl:'',controlsTpl:'
',inputTpl:"",errorTpl:'
',buttonsTpl:'',submitTpl:'',cancelTpl:'',buttonsClass:"",inputClass:"",postrender:function(){switch(this.directiveName){case"editableText":case"editableSelect":case"editableTextarea":case"editableEmail":case"editableTel":case"editableNumber":case"editableUrl":case"editableSearch":case"editableDate":case"editableDatetime":case"editableTime":case"editableMonth":case"editableWeek":if(this.inputEl.addClass("form-control"),this.theme.inputClass){if(this.inputEl.attr("multiple")&&("input-sm"===this.theme.inputClass||"input-lg"===this.theme.inputClass))break;this.inputEl.addClass(this.theme.inputClass)}}this.buttonsEl&&this.theme.buttonsClass&&this.buttonsEl.find("button").addClass(this.theme.buttonsClass)}}}}),function(e,t,n){"use strict";function r(e){return F(e)?e:Object.keys(e).map(function(t){return e[t]})}function a(e){return null===e}function o(e,t){return-1==Object.keys(e).map(function(r){return t[r]!==n&&t[r]==e[r]}).indexOf(!1)}function i(e,t){if(""===t)return e;var n=e.indexOf(t.charAt(0));return-1!==n&&i(e.substr(n+1),t.substr(1))}function s(e,t,n){var r=0;return e.filter(function(e){var a=D(n)?t>r&&n(e):t>r;return r=a?r+1:r,a})}function l(e,t,n){return n.round(e*n.pow(10,t))/n.pow(10,t)}function u(e,t,n){return t=t||[],Object.keys(e).forEach(function(r){if(T(e[r])&&!F(e[r])){var a=n?n+"."+r:n;u(e[r],t,a||r)}else{var o=n?n+"."+r:r;t.push(o)}}),t}function c(e){return e&&e.$evalAsync&&e.$watch}function d(){return function(e,t){return e>t}}function f(){return function(e,t){return e>=t}}function m(){return function(e,t){return t>e}}function p(){return function(e,t){return t>=e}}function b(){return function(e,t){return e==t}}function h(){return function(e,t){return e!=t}}function v(){return function(e,t){return e===t}}function g(){return function(e,t){return e!==t}}function _(e){return function(t,n){return t=T(t)?r(t):t,!(!F(t)||E(n))&&t.some(function(t){return T(t)||j(n)?e(n)(t):t===n})}}function $(e,t){return t=t||0,t>=e.length?e:F(e[t])?$(e.slice(0,t).concat(e[t],e.slice(t+1)),t):$(e,t+1)}function w(e){return function(t,n){function a(e,t){return!E(t)&&e.some(function(e){return N(e,t)})}if(t=T(t)?r(t):t,!F(t))return t;var o=[],i=e(n);return t.filter(E(n)?function(e,t,n){return n.indexOf(e)===t}:function(e){var t=i(e);return!a(o,t)&&(o.push(t),!0)})}}function y(e,t,n){return t?e+n+y(e,--t,n):e}var D=t.isDefined,E=t.isUndefined,j=t.isFunction,C=t.isString,R=t.isNumber,T=t.isObject,F=t.isArray,x=t.forEach,A=t.extend,S=t.copy,N=t.equals;String.prototype.contains||(String.prototype.contains=function(){return-1!==String.prototype.indexOf.apply(this,arguments)}),t.module("a8m.angular",[]).filter("isUndefined",function(){return function(e){return t.isUndefined(e)}}).filter("isDefined",function(){return function(e){return t.isDefined(e)}}).filter("isFunction",function(){return function(e){return t.isFunction(e)}}).filter("isString",function(){return function(e){return t.isString(e)}}).filter("isNumber",function(){return function(e){return t.isNumber(e)}}).filter("isArray",function(){return function(e){return t.isArray(e)}}).filter("isObject",function(){return function(e){return t.isObject(e)}}).filter("isEqual",function(){return function(e,n){return t.equals(e,n)}}),t.module("a8m.conditions",[]).filter({isGreaterThan:d,">":d,isGreaterThanOrEqualTo:f,">=":f,isLessThan:m,"<":m,isLessThanOrEqualTo:p,"<=":p,isEqualTo:b,"==":b,isNotEqualTo:h,"!=":h,isIdenticalTo:v,"===":v,isNotIdenticalTo:g,"!==":g}),t.module("a8m.is-null",[]).filter("isNull",function(){return function(e){return a(e)}}),t.module("a8m.after-where",[]).filter("afterWhere",function(){return function(e,t){if(e=T(e)?r(e):e,!F(e)||E(t))return e;var n=e.map(function(e){return o(t,e)}).indexOf(!0);return e.slice(-1===n?0:n)}}),t.module("a8m.after",[]).filter("after",function(){return function(e,t){return e=T(e)?r(e):e,F(e)?e.slice(t):e}}),t.module("a8m.before-where",[]).filter("beforeWhere",function(){return function(e,t){if(e=T(e)?r(e):e,!F(e)||E(t))return e;var n=e.map(function(e){return o(t,e)}).indexOf(!0);return e.slice(0,-1===n?e.length:++n)}}),t.module("a8m.before",[]).filter("before",function(){return function(e,t){return e=T(e)?r(e):e,F(e)?e.slice(0,t?--t:t):e}}),t.module("a8m.concat",[]).filter("concat",[function(){return function(e,t){if(E(t))return e;if(F(e))return e.concat(T(t)?r(t):t);if(T(e)){return r(e).concat(T(t)?r(t):t)}return e}}]),t.module("a8m.contains",[]).filter({contains:["$parse",_],some:["$parse",_]}),t.module("a8m.count-by",[]).filter("countBy",["$parse",function(e){return function(t,n){var a,o={},i=e(n);return t=T(t)?r(t):t,!F(t)||E(n)?t:(t.forEach(function(e){a=i(e),o[a]||(o[a]=0),o[a]++}),o)}}]),t.module("a8m.defaults",[]).filter("defaults",["$parse",function(e){return function(t,n){if(t=T(t)?r(t):t,!F(t)||!T(n))return t;var a=u(n);return t.forEach(function(t){a.forEach(function(r){var a=e(r),o=a.assign;E(a(t))&&o(t,a(n))})}),t}}]),t.module("a8m.every",[]).filter("every",["$parse",function(e){return function(t,n){return t=T(t)?r(t):t,!(F(t)&&!E(n))||t.every(function(t){return T(t)||j(n)?e(n)(t):t===n})}}]),t.module("a8m.filter-by",[]).filter("filterBy",["$parse",function(e){return function(t,a,o){var i;return o=C(o)||R(o)?String(o).toLowerCase():n,t=T(t)?r(t):t,!F(t)||E(o)?t:t.filter(function(t){return a.some(function(n){if(~n.indexOf("+")){var r=n.replace(new RegExp("\\s","g"),"").split("+");i=r.reduce(function(n,r,a){return 1===a?e(n)(t)+" "+e(r)(t):n+" "+e(r)(t)})}else i=e(n)(t);return!(!C(i)&&!R(i))&&String(i).toLowerCase().contains(o)})})}}]),t.module("a8m.first",[]).filter("first",["$parse",function(e){return function(t){var a,o,i;return t=T(t)?r(t):t,F(t)?(i=Array.prototype.slice.call(arguments,1),a=R(i[0])?i[0]:1,o=R(i[0])?R(i[1])?n:i[1]:i[0],i.length?s(t,a,o?e(o):o):t[0]):t}}]),t.module("a8m.flatten",[]).filter("flatten",function(){return function(e,t){return t=t||!1,e=T(e)?r(e):e,F(e)?t?[].concat.apply([],e):$(e,0):e}}),t.module("a8m.fuzzy-by",[]).filter("fuzzyBy",["$parse",function(e){return function(t,n,a,o){var s,l,u=o||!1;return t=T(t)?r(t):t,!F(t)||E(n)||E(a)?t:(l=e(n),t.filter(function(e){return s=l(e),!!C(s)&&(s=u?s:s.toLowerCase(),a=u?a:a.toLowerCase(),!1!==i(s,a))}))}}]),t.module("a8m.fuzzy",[]).filter("fuzzy",function(){return function(e,t,n){function a(e,t){var n,r;return 0=0&&R(t)&&isFinite(t)?1024>t?l(t,n,e)+" B":1048576>t?l(t/1024,n,e)+" KB":1073741824>t?l(t/1048576,n,e)+" MB":l(t/1073741824,n,e)+" GB":"NaN"}}]),t.module("a8m.math.degrees",["a8m.math"]).filter("degrees",["$math",function(e){return function(t,n){if(R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)){var r=180*t/e.PI;return e.round(r*e.pow(10,n))/e.pow(10,n)}return"NaN"}}]),t.module("a8m.math.kbFmt",["a8m.math"]).filter("kbFmt",["$math",function(e){return function(t,n){return R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)?1024>t?l(t,n,e)+" KB":1048576>t?l(t/1024,n,e)+" MB":l(t/1048576,n,e)+" GB":"NaN"}}]),t.module("a8m.math",[]).factory("$math",["$window",function(e){return e.Math}]),t.module("a8m.math.max",["a8m.math"]).filter("max",["$math","$parse",function(e,t){function n(n,r){var a=n.map(function(e){return t(r)(e)});return a.indexOf(e.max.apply(e,a))}return function(t,r){return F(t)?E(r)?e.max.apply(e,t):t[n(t,r)]:t}}]),t.module("a8m.math.min",["a8m.math"]).filter("min",["$math","$parse",function(e,t){function n(n,r){var a=n.map(function(e){return t(r)(e)});return a.indexOf(e.min.apply(e,a))}return function(t,r){return F(t)?E(r)?e.min.apply(e,t):t[n(t,r)]:t}}]),t.module("a8m.math.percent",["a8m.math"]).filter("percent",["$math","$window",function(e,t){return function(n,r,a){var o=C(n)?t.Number(n):n;return r=r||100,a=a||!1,!R(o)||t.isNaN(o)?n:a?e.round(o/r*100):o/r*100}}]),t.module("a8m.math.radians",["a8m.math"]).filter("radians",["$math",function(e){return function(t,n){if(R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)){var r=3.14159265359*t/180;return e.round(r*e.pow(10,n))/e.pow(10,n)}return"NaN"}}]),t.module("a8m.math.radix",[]).filter("radix",function(){return function(e,t){var n=/^[2-9]$|^[1-2]\d$|^3[0-6]$/;return R(e)&&n.test(t)?e.toString(t).toUpperCase():e}}),t.module("a8m.math.shortFmt",["a8m.math"]).filter("shortFmt",["$math",function(e){return function(t,n){return R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)?1e3>t?t:1e6>t?l(t/1e3,n,e)+" K":1e9>t?l(t/1e6,n,e)+" M":l(t/1e9,n,e)+" B":"NaN"}}]),t.module("a8m.math.sum",[]).filter("sum",function(){return function(e,t){return F(e)?e.reduce(function(e,t){return e+t},t||0):e}}),t.module("a8m.ends-with",[]).filter("endsWith",function(){return function(e,t,n){var r,a=n||!1;return!C(e)||E(t)?e:(e=a?e:e.toLowerCase(),r=e.length-t.length,-1!==e.indexOf(a?t:t.toLowerCase(),r))}}),t.module("a8m.latinize",[]).filter("latinize",[function(){function e(e){return e.replace(/[^\u0000-\u007E]/g,function(e){return n[e]||e})}for(var t=[{base:"A",letters:"AⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ"},{base:"AA",letters:"Ꜳ"},{base:"AE",letters:"ÆǼǢ"},{base:"AO",letters:"Ꜵ"},{base:"AU",letters:"Ꜷ"},{base:"AV",letters:"ꜸꜺ"},{base:"AY",letters:"Ꜽ"},{base:"B",letters:"BⒷBḂḄḆɃƂƁ"},{base:"C",letters:"CⒸCĆĈĊČÇḈƇȻꜾ"},{base:"D",letters:"DⒹDḊĎḌḐḒḎĐƋƊƉꝹ"},{base:"DZ",letters:"DZDŽ"},{base:"Dz",letters:"DzDž"},{base:"E",letters:"EⒺEÈÉÊỀẾỄỂẼĒḔḖĔĖËẺĚȄȆẸỆȨḜĘḘḚƐƎ"},{base:"F",letters:"FⒻFḞƑꝻ"},{base:"G",letters:"GⒼGǴĜḠĞĠǦĢǤƓꞠꝽꝾ"},{base:"H",letters:"HⒽHĤḢḦȞḤḨḪĦⱧⱵꞍ"},{base:"I",letters:"IⒾIÌÍÎĨĪĬİÏḮỈǏȈȊỊĮḬƗ"},{base:"J",letters:"JⒿJĴɈ"},{base:"K",letters:"KⓀKḰǨḲĶḴƘⱩꝀꝂꝄꞢ"},{base:"L",letters:"LⓁLĿĹĽḶḸĻḼḺŁȽⱢⱠꝈꝆꞀ"},{base:"LJ",letters:"LJ"},{base:"Lj",letters:"Lj"},{base:"M",letters:"MⓂMḾṀṂⱮƜ"},{base:"N",letters:"NⓃNǸŃÑṄŇṆŅṊṈȠƝꞐꞤ"},{base:"NJ",letters:"NJ"},{base:"Nj",letters:"Nj"},{base:"O",letters:"OⓄOÒÓÔỒỐỖỔÕṌȬṎŌṐṒŎȮȰÖȪỎŐǑȌȎƠỜỚỠỞỢỌỘǪǬØǾƆƟꝊꝌ"},{base:"OI",letters:"Ƣ"},{base:"OO",letters:"Ꝏ"},{base:"OU",letters:"Ȣ"},{base:"OE",letters:"ŒŒ"},{base:"oe",letters:"œœ"},{base:"P",letters:"PⓅPṔṖƤⱣꝐꝒꝔ"},{base:"Q",letters:"QⓆQꝖꝘɊ"},{base:"R",letters:"RⓇRŔṘŘȐȒṚṜŖṞɌⱤꝚꞦꞂ"},{base:"S",letters:"SⓈSẞŚṤŜṠŠṦṢṨȘŞⱾꞨꞄ"},{base:"T",letters:"TⓉTṪŤṬȚŢṰṮŦƬƮȾꞆ"},{base:"TZ",letters:"Ꜩ"},{base:"U",letters:"UⓊUÙÚÛŨṸŪṺŬÜǛǗǕǙỦŮŰǓȔȖƯỪỨỮỬỰỤṲŲṶṴɄ"},{base:"V",letters:"VⓋVṼṾƲꝞɅ"},{base:"VY",letters:"Ꝡ"},{base:"W",letters:"WⓌWẀẂŴẆẄẈⱲ"},{base:"X",letters:"XⓍXẊẌ"},{base:"Y",letters:"YⓎYỲÝŶỸȲẎŸỶỴƳɎỾ"},{base:"Z",letters:"ZⓏZŹẐŻŽẒẔƵȤⱿⱫꝢ"},{base:"a",letters:"aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐ"},{base:"aa",letters:"ꜳ"},{base:"ae",letters:"æǽǣ"},{base:"ao",letters:"ꜵ"},{base:"au",letters:"ꜷ"},{base:"av",letters:"ꜹꜻ"},{base:"ay",letters:"ꜽ"},{base:"b",letters:"bⓑbḃḅḇƀƃɓ"},{base:"c",letters:"cⓒcćĉċčçḉƈȼꜿↄ"},{base:"d",letters:"dⓓdḋďḍḑḓḏđƌɖɗꝺ"},{base:"dz",letters:"dzdž"},{base:"e",letters:"eⓔeèéêềếễểẽēḕḗĕėëẻěȅȇẹệȩḝęḙḛɇɛǝ"},{base:"f",letters:"fⓕfḟƒꝼ"},{base:"g",letters:"gⓖgǵĝḡğġǧģǥɠꞡᵹꝿ"},{base:"h",letters:"hⓗhĥḣḧȟḥḩḫẖħⱨⱶɥ"},{base:"hv",letters:"ƕ"},{base:"i",letters:"iⓘiìíîĩīĭïḯỉǐȉȋịįḭɨı"},{base:"j",letters:"jⓙjĵǰɉ"},{base:"k",letters:"kⓚkḱǩḳķḵƙⱪꝁꝃꝅꞣ"},{base:"l",letters:"lⓛlŀĺľḷḹļḽḻſłƚɫⱡꝉꞁꝇ"},{base:"lj",letters:"lj"},{base:"m",letters:"mⓜmḿṁṃɱɯ"},{base:"n",letters:"nⓝnǹńñṅňṇņṋṉƞɲʼnꞑꞥ"},{base:"nj",letters:"nj"},{base:"o",letters:"oⓞoòóôồốỗổõṍȭṏōṑṓŏȯȱöȫỏőǒȍȏơờớỡởợọộǫǭøǿɔꝋꝍɵ"},{base:"oi",letters:"ƣ"},{base:"ou",letters:"ȣ"},{base:"oo",letters:"ꝏ"},{base:"p",letters:"pⓟpṕṗƥᵽꝑꝓꝕ"},{base:"q",letters:"qⓠqɋꝗꝙ"},{base:"r",letters:"rⓡrŕṙřȑȓṛṝŗṟɍɽꝛꞧꞃ"},{base:"s",letters:"sⓢsßśṥŝṡšṧṣṩșşȿꞩꞅẛ"},{base:"t",letters:"tⓣtṫẗťṭțţṱṯŧƭʈⱦꞇ"},{base:"tz",letters:"ꜩ"},{base:"u",letters:"uⓤuùúûũṹūṻŭüǜǘǖǚủůűǔȕȗưừứữửựụṳųṷṵʉ"},{base:"v",letters:"vⓥvṽṿʋꝟʌ"},{base:"vy",letters:"ꝡ"},{base:"w",letters:"wⓦwẁẃŵẇẅẘẉⱳ"},{base:"x",letters:"xⓧxẋẍ"},{base:"y",letters:"yⓨyỳýŷỹȳẏÿỷẙỵƴɏỿ"},{base:"z",letters:"zⓩzźẑżžẓẕƶȥɀⱬꝣ"}],n={},r=0;r<]*>/g,""):e}}),t.module("a8m.test",[]).filter("test",function(){return function(e,t,n){var r=new RegExp(t,n);return C(e)?r.test(e):e}}),t.module("a8m.trim",[]).filter("trim",function(){return function(e,t){var n=t||"\\s";return C(e)?e.replace(new RegExp("^"+n+"+|"+n+"+$","g"),""):e}}),t.module("a8m.truncate",[]).filter("truncate",function(){return function(e,t,n,r){return t=E(t)?e.length:t,r=r||!1,n=n||"",!C(e)||e.length<=t?e:e.substring(0,r?-1===e.indexOf(" ",t)?e.length:e.indexOf(" ",t):t)+n}}),t.module("a8m.ucfirst",[]).filter("ucfirst",[function(){return function(e){return C(e)?e.split(" ").map(function(e){return e.charAt(0).toUpperCase()+e.substring(1)}).join(" "):e}}]),t.module("a8m.uri-component-encode",[]).filter("uriComponentEncode",["$window",function(e){return function(t){return C(t)?e.encodeURIComponent(t):t}}]),t.module("a8m.uri-encode",[]).filter("uriEncode",["$window",function(e){return function(t){return C(t)?e.encodeURI(t):t}}]),t.module("a8m.wrap",[]).filter("wrap",function(){return function(e,t,n){return C(e)&&D(t)?[t,e,n||t].join(""):e}}),t.module("a8m.filter-watcher",[]).provider("filterWatcher",function(){this.$get=["$window","$rootScope",function(e,n){function r(e,n){return[e,t.toJson(n)].join("#").replace(/"/g,"")}function a(e){var t=e.targetScope.$id;x(d[t],function(e){delete u[e]}),delete d[t]}function o(){f(function(){n.$$phase||(u={})})}function i(e,t){var n=e.$id;return E(d[n])&&(e.$on("$destroy",a),d[n]=[]),d[n].push(t)}function s(e,t){var n=r(e,t);return u[n]}function l(e,t,n,a){var s=r(e,t);return u[s]=a,c(n)?i(n,s):o(),a}var u={},d={},f=e.setTimeout;return{isMemoized:s,memoize:l}}]}),t.module("angular.filter",["a8m.ucfirst","a8m.uri-encode","a8m.uri-component-encode","a8m.slugify","a8m.latinize","a8m.strip-tags","a8m.stringular","a8m.truncate","a8m.starts-with","a8m.ends-with","a8m.wrap","a8m.trim","a8m.ltrim","a8m.rtrim","a8m.repeat","a8m.test","a8m.match","a8m.to-array","a8m.concat","a8m.contains","a8m.unique","a8m.is-empty","a8m.after","a8m.after-where","a8m.before","a8m.before-where","a8m.defaults","a8m.where","a8m.reverse","a8m.remove","a8m.remove-with","a8m.group-by","a8m.count-by","a8m.search-field","a8m.fuzzy-by","a8m.fuzzy","a8m.omit","a8m.pick","a8m.every","a8m.filter-by","a8m.xor","a8m.map","a8m.first","a8m.last","a8m.flatten","a8m.join","a8m.math","a8m.math.max","a8m.math.min","a8m.math.percent","a8m.math.radix","a8m.math.sum","a8m.math.degrees","a8m.math.radians","a8m.math.byteFmt","a8m.math.kbFmt","a8m.math.shortFmt","a8m.angular","a8m.conditions","a8m.is-null","a8m.filter-watcher"])}(window,window.angular),define("job-roles/modules/job-roles.core",["common/angular","common/ui-select","common/directives/angular-date/date-input","common/modules/directives","common/modules/routers/compu-ng-route","common/filters/angular-date/format-date","common/services/angular-date/date-format","common/services/dom-event-trigger","common/services/pub-sub","job-roles/vendor/angular-editable","job-roles/vendor/angular-filter"],function(e){"use strict";e.module("hrjobroles.core",["angular.filter","ngAnimate","ngSanitize","ngResource","ui.bootstrap","ui.select","xeditable","common.angularDate","common.directives","common.services","compuNgRoute"])}),define("job-roles/filters/get-active-values.filter",["common/lodash"],function(e){"use strict";function t(t){return t.debug("Filter: getActiveValues"),function(t){var n={};return e.each(t,function(e,t){"1"===e.is_active&&(n[t]=e)}),n}}return t.__name="getActiveValues",t.$inject=["$log"],t}),define("job-roles/modules/job-roles.filters",["common/angular","job-roles/filters/get-active-values.filter"],function(e,t){"use strict";return e.module("hrjobroles.filters",[]).filter(t.__name,t)}),define("job-roles/modules/job-roles.run",["common/angular"],function(e){"use strict";function t(e,t,n,r){n.theme="bs3",t.contactId=r.contactId,t.pathBaseUrl=r.pathBaseUrl,t.pathTpl=r.pathTpl,t.pathIncludeTpl=r.pathIncludeTpl,t.prefix=r.classNamePrefix}e.module("hrjobroles.run",["hrjobroles.constants"]).run(t),t.$inject=["$q","$rootScope","editableOptions","settings"]}),define("job-roles/services/date-validation.service",["common/moment"],function(e){function t(t){function n(e,t){e.isValid()||l("Date is not valid!!",t)}function r(e,t){e.isSameOrAfter(t)&&l("Start Date cannot be the same as or after the End Date.",["start_date","end_date"])}function a(e,t){e.isBefore(t)&&l("Start Date cannot be lower than Contract Start Date.",["start_date"])}function o(e,t){e.isAfter(t)&&l("Start Date cannot be higher than Contract End Date.",["start_date"])}function i(e,t){e.isAfter(t)&&l("End Date cannot be higher than Contract End Date.",["end_date"])}function s(t,n){return t instanceof Date&&(t=e(t).valueOf()),e(t,n,!0).startOf("day")}var l=function(e,t){throw new Error(e,t[0])},u={dateFormats:["x","YYYY-MM-DD"],setErrorCallback:function(e){if("function"!=typeof e)throw new TypeError("Error callback must be a function.");l=e},validate:function(e,t,l,u){e=s(e,this.dateFormats),l=s(l,this.dateFormats),u=s(u,this.dateFormats),n(e,["start_date"]),o(e,u),a(e,l),(0===t||t)&&(t=s(t,this.dateFormats),n(t,["end_date"]),i(t,u),r(e,t))}};return t.DATE_FORMAT&&u.dateFormats.push(t.DATE_FORMAT.toUpperCase()),u}return t.__name="dateValidation",t.$inject=["HR_settings"],t}),define("job-roles/services/filters.service",[],function(){"use strict";function e(){return{isNotUndefined:function(e){try{return e.constructor===Array?e.filter(function(e){return"undefined"!==e&&void 0!==e}):e}catch(t){return e}},issetCostCentre:function(e){try{return e.constructor===Array?e.filter(function(e){return""!==e.cost_centre_id&&("1"===e.type&&parseInt(e.percentage)>0||"0"===e.type&&parseInt(e.amount)>0)}):e}catch(t){return e}},issetFunder:function(e){try{return e.constructor===Array?e.filter(function(e){return""!==e.funder_id&&("1"===e.type&&parseInt(e.percentage)>0||"0"===e.type&&parseInt(e.amount)>0)}):e}catch(t){return e}}}}return e.__name="filtersService",e}),define("job-roles/services/job-role.service",["common/lodash"],function(e){"use strict";function t(t,n,r){function a(n){var r=n["api.HRJobContractRevision.get"].values;delete n["api.HRJobContractRevision.get"],n.revisions=e.compact(r.map(function(e){var r=e["api.HRJobDetails.getsingle"];return r.period_start_date===n.period_start_date&&r.period_end_date===n.period_end_date?null:(r.period_start_date=t("formatDate")(r.period_start_date),r.period_end_date=t("formatDate")(r.period_end_date),r)}))}return{getContracts:function(e){var t=r.defer();return CRM.api3("HRJobContract","get",{sequential:1,contact_id:e,deleted:0,return:"title,period_end_date,period_start_date","api.HRJobContractRevision.get":{jobcontract_id:"$value.id","api.HRJobDetails.getsingle":{jobcontract_revision_id:"$value.id"}}}).done(function(e){e.values.forEach(a),t.resolve(e)}).error(function(){t.reject("An error occured while fetching items")}),t.promise},getAllJobRoles:function(e){var t=r.defer();return CRM.api3("HrJobRoles","get",{sequential:1,return:"id,job_contract_id,title,description,status,funder,funder_val_type,percent_pay_funder,amount_pay_funder,cost_center,cost_center_val_type,percent_pay_cost_center,amount_pay_cost_center,level_type,location,region,department,end_date,start_date",job_contract_id:{IN:e}}).done(function(e){t.resolve(e)}).error(function(e){t.reject("An error occured while fetching items")}),t.promise},deleteJobRole:function(e){var t=r.defer();return CRM.api3("HrJobRoles","delete",{sequential:1,id:e}).done(function(e){t.resolve(e)}).error(function(e){t.reject("An error occured while deleting items")}),t.promise},createJobRole:function(e){var t="|",n="|",a="|",o="|",i="|",s="|",l="|",u="|";if(void 0!==e.funders)for(var c=0,d=e.funders.length;c-1&&t.start.push(e),r.indexOf("end_date")>-1&&t.end.push(e)}),h.validate(e.start,e.end,e.contractStart,e.contractEnd),0===n}function $e(e){e.start_date.$error.custom=[],e.end_date.$error.custom=[];var t=L(e.contract.$viewValue);return void 0===t?"Contract is missing":!!_e({start:e.start_date.$viewValue,end:e.end_date.$viewValue,contractStart:t.start_date,contractEnd:t.end_date},{start:e.start_date.$error.custom,end:e.end_date.$error.custom})||"Error"}function we(e){if("title"===e||" "===e)return"Title cannot be title!"}a.debug("Controller: JobRolesController");var ye=r("formatDate"),De={},Ee=r("getActiveValues"),je=["funders","cost_centers"],Ce=this;Ce.contactId=m.contactId,Ce.format=p.DATE_FORMAT,Ce.loading=!0,Ce.pastJobRoles=[],Ce.presentJobRoles=[],Ce.collapsedRows=[],Ce.contactList=[],Ce.editData={},Ce.viewTab=[],Ce.CalendarShow=[],Ce.contractsData=[],Ce.DepartmentsData={},Ce.LevelsData={},Ce.LocationsData={},Ce.RegionsData={},Ce.addNewRoleUrl=m.pathBaseUrl+m.pathIncludeTpl+"add_new_role.html",Ce.jobRolePanelUrl=m.pathBaseUrl+m.pathIncludeTpl+"job_role_panel.html",Ce.rowTypes={},Ce.rowTypes[0]={id:0,name:"Fixed"},Ce.rowTypes[1]={id:1,name:"%"},Ce.addAdditionalRow=$,Ce.addNewRole=w,Ce.cancelNewRole=y,Ce.changeTab=D,Ce.checkIfDatesAreCustom=E,Ce.checkNewRole=j,Ce.collapseRow=C,Ce.deleteAdditionalRow=x,Ce.dpOpen=S,Ce.getContactList=J,Ce.getCostLabel=U,Ce.initData=P,Ce.isChanged=G,Ce.isOpen=Z,Ce.isRowCollapsed=X,Ce.isTab=Q,Ce.onAfterSave=ee,Ce.onCancel=te,Ce.onContractEdited=ne,Ce.onContractSelected=re,Ce.open=ae,Ce.removeRole=ie,Ce.saveNewRole=se,Ce.select=le,Ce.showRowType=ue,Ce.showSave=ce,Ce.status="",Ce.today=fe,Ce.updateAdditionalRowType=me,Ce.updateRole=ve,Ce.validateRole=$e,Ce.validateTitle=we,Ce.openOptionsEditor=q,function(){de(),Ce.today(),o.all([W(),I(Ce.contactId),Ce.getContactList()]).then(function(){Ce.loading=!1})}()}return r.__name="JobRolesController",r.$inject=["$filter","$log","$q","$rootElement","$route","$routeParams","$scope","$timeout","$uibModal","DOMEventTrigger","settings","HR_settings","crmAngService","dateValidation","filtersService","jobRoleService","pubSub"],r}),define("job-roles/controllers/modal-dialog.controller",[],function(){"use strict";function e(e,t,n,r){function a(){e.dismiss("Cancel")}function o(t){e.close(t||!0)}t.debug("Controller: ModalDialogController");var i=this;i.copyCancel=r.copyCancel||"Cancel",i.copyConfirm=r.copyConfirm||"Yes",i.msg=r.msg||"",i.title=r.title||"CiviHR Job Roles",i.cancel=a,i.confirm=o}return e.__name="ModalDialogController",e.$inject=["$uibModalInstance","$log","$timeout","content"],e}),define("job-roles/modules/job-roles.controllers",["common/angular","job-roles/controllers/job-roles.controller","job-roles/controllers/modal-dialog.controller"],function(e,t,n){"use strict";return e.module("hrjobroles.controllers",[]).controller(t.__name,t).controller(n.__name,n)}),angular.module("xeditable",[]).value("editableOptions",{theme:"default",buttons:"right",blurElem:"cancel",blurForm:"ignore",activate:"focus"}),angular.module("xeditable").directive("editableBsdate",["editableDirectiveFactory",function(e){return e({directiveName:"editableBsdate",inputTpl:''})}]),angular.module("xeditable").directive("editableBstime",["editableDirectiveFactory",function(e){return e({directiveName:"editableBstime",inputTpl:"",render:function(){this.parent.render.call(this);var e=angular.element('
');e.attr("ng-model",this.inputEl.attr("ng-model")),this.inputEl.removeAttr("ng-model"),this.attrs.eNgChange&&(e.attr("ng-change",this.inputEl.attr("ng-change")),this.inputEl.removeAttr("ng-change")),this.inputEl.wrap(e)}})}]),angular.module("xeditable").directive("editableCheckbox",["editableDirectiveFactory",function(e){return e({directiveName:"editableCheckbox",inputTpl:'',render:function(){this.parent.render.call(this),this.attrs.eTitle&&(this.inputEl.wrap(""),this.inputEl.after(angular.element("").text(this.attrs.eTitle)))},autosubmit:function(){var e=this;e.inputEl.bind("change",function(){setTimeout(function(){e.scope.$apply(function(){e.scope.$form.$submit()})},500)})}})}]),angular.module("xeditable").directive("editableChecklist",["editableDirectiveFactory","editableNgOptionsParser",function(e,t){return e({directiveName:"editableChecklist",inputTpl:"",useCopy:!0,render:function(){this.parent.render.call(this);var e=t(this.attrs.eNgOptions),n='';this.inputEl.removeAttr("ng-model"),this.inputEl.removeAttr("ng-options"),this.inputEl.html(n)}})}]),function(){var e="text|email|tel|number|url|search|color|date|datetime|time|month|week".split("|");angular.forEach(e,function(e){var t="editable"+e.charAt(0).toUpperCase()+e.slice(1);angular.module("xeditable").directive(t,["editableDirectiveFactory",function(n){return n({directiveName:t,inputTpl:''})}])}),angular.module("xeditable").directive("editableRange",["editableDirectiveFactory",function(e){return e({directiveName:"editableRange",inputTpl:'',render:function(){this.parent.render.call(this),this.inputEl.after("{{$data}}")}})}])}(),angular.module("xeditable").directive("editableRadiolist",["editableDirectiveFactory","editableNgOptionsParser",function(e,t){return e({directiveName:"editableRadiolist",inputTpl:"",render:function(){this.parent.render.call(this);var e=t(this.attrs.eNgOptions),n='';this.inputEl.removeAttr("ng-model"),this.inputEl.removeAttr("ng-options"),this.inputEl.html(n)},autosubmit:function(){var e=this;e.inputEl.bind("change",function(){setTimeout(function(){e.scope.$apply(function(){e.scope.$form.$submit()})},500)})}})}]),angular.module("xeditable").directive("editableSelect",["editableDirectiveFactory",function(e){return e({directiveName:"editableSelect",inputTpl:"",autosubmit:function(){var e=this;e.inputEl.bind("change",function(){e.scope.$apply(function(){e.scope.$form.$submit()})})}})}]),angular.module("xeditable").directive("editableTextarea",["editableDirectiveFactory",function(e){return e({directiveName:"editableTextarea",inputTpl:"",addListeners:function(){var e=this;e.parent.addListeners.call(e),e.single&&"no"!==e.buttons&&e.autosubmit()},autosubmit:function(){var e=this;e.inputEl.bind("keydown",function(t){(t.ctrlKey||t.metaKey)&&13===t.keyCode&&e.scope.$apply(function(){e.scope.$form.$submit()})})}})}]),angular.module("xeditable").factory("editableController",["$q","editableUtils",function(e,t){function n(e,n,r,a,o,i,s,l,u){var c,d,f=this;f.scope=e,f.elem=r,f.attrs=n,f.inputEl=null,f.editorEl=null,f.single=!0,f.error="",f.theme=o[i.theme]||o.default,f.parent={},f.inputTpl="",f.directiveName="",f.useCopy=!1,f.single=null,f.buttons="right",f.init=function(t){if(f.single=t,f.name=n.eName||n[f.directiveName],!n[f.directiveName])throw"You should provide value for `"+f.directiveName+"` in editable element!";c=a(n[f.directiveName]),f.buttons=f.single?f.attrs.buttons||i.buttons:"no",n.eName&&f.scope.$watch("$data",function(e){f.scope.$form.$data[n.eName]=e}),n.onshow&&(f.onshow=function(){return f.catchError(a(n.onshow)(e))}),n.onhide&&(f.onhide=function(){return a(n.onhide)(e)}),n.oncancel&&(f.oncancel=function(){return a(n.oncancel)(e)}),n.onbeforesave&&(f.onbeforesave=function(){return f.catchError(a(n.onbeforesave)(e))}),n.onaftersave&&(f.onaftersave=function(){return f.catchError(a(n.onaftersave)(e))}),e.$parent.$watch(n[f.directiveName],function(){f.handleEmpty()})},f.render=function(){var e=f.theme;f.inputEl=angular.element(f.inputTpl),f.controlsEl=angular.element(e.controlsTpl),f.controlsEl.append(f.inputEl),"no"!==f.buttons&&(f.buttonsEl=angular.element(e.buttonsTpl),f.submitEl=angular.element(e.submitTpl),f.cancelEl=angular.element(e.cancelTpl),f.buttonsEl.append(f.submitEl).append(f.cancelEl),f.controlsEl.append(f.buttonsEl),f.inputEl.addClass("editable-has-buttons")),f.errorEl=angular.element(e.errorTpl),f.controlsEl.append(f.errorEl),f.editorEl=angular.element(f.single?e.formTpl:e.noformTpl),f.editorEl.append(f.controlsEl);for(var r in n.$attr)if(!(r.length<=1)){var a=!1,o=r.substring(1,2);if("e"===r.substring(0,1)&&o===o.toUpperCase()&&"Form"!==(a=r.substring(1))&&"NgSubmit"!==a){a=a.substring(0,1).toLowerCase()+t.camelToDash(a.substring(1));var s=""===n[r]?a:n[r];f.inputEl.attr(a,s)}}f.inputEl.addClass("editable-input"),f.inputEl.attr("ng-model","$data"),f.editorEl.addClass(t.camelToDash(f.directiveName)),f.single&&(f.editorEl.attr("editable-form","$form"),f.editorEl.attr("blur",f.attrs.blur||("no"===f.buttons?"cancel":i.blurElem))),angular.isFunction(e.postrender)&&e.postrender.call(f)},f.setLocalValue=function(){f.scope.$data=f.useCopy?angular.copy(c(e.$parent)):c(e.$parent)},f.show=function(){return f.setLocalValue(),f.render(),r.after(f.editorEl),l(f.editorEl)(e),f.addListeners(),r.addClass("editable-hide"),f.onshow()},f.hide=function(){return f.editorEl.remove(),r.removeClass("editable-hide"),f.onhide()},f.cancel=function(){f.oncancel()},f.addListeners=function(){f.inputEl.bind("keyup",function(e){if(f.single)switch(e.keyCode){case 27:f.scope.$apply(function(){f.scope.$form.$cancel()})}}),f.single&&"no"===f.buttons&&f.autosubmit(),f.editorEl.bind("click",function(e){1===e.which&&f.scope.$form.$visible&&(f.scope.$form._clicked=!0)})},f.setWaiting=function(e){e?(d=!f.inputEl.attr("disabled")&&!f.inputEl.attr("ng-disabled")&&!f.inputEl.attr("ng-enabled"))&&(f.inputEl.attr("disabled","disabled"),f.buttonsEl&&f.buttonsEl.find("button").attr("disabled","disabled")):d&&(f.inputEl.removeAttr("disabled"),f.buttonsEl&&f.buttonsEl.find("button").removeAttr("disabled"))},f.activate=function(){setTimeout(function(){var e=f.inputEl[0];"focus"===i.activate&&e.focus&&e.focus(),"select"===i.activate&&e.select&&e.select()},0)},f.setError=function(t){angular.isObject(t)||(e.$error=t,f.error=t)},f.catchError=function(e,t){return angular.isObject(e)&&!0!==t?u.when(e).then(angular.bind(this,function(e){this.catchError(e,!0)}),angular.bind(this,function(e){this.catchError(e,!0)})):t&&angular.isObject(e)&&e.status&&200!==e.status&&e.data&&angular.isString(e.data)?(this.setError(e.data),e=e.data):angular.isString(e)&&this.setError(e),e},f.save=function(){c.assign(e.$parent,angular.copy(f.scope.$data))},f.handleEmpty=function(){var t=c(e.$parent),n=null===t||void 0===t||""===t||angular.isArray(t)&&0===t.length;r.toggleClass("editable-empty",n)},f.autosubmit=angular.noop,f.onshow=angular.noop,f.onhide=angular.noop,f.oncancel=angular.noop,f.onbeforesave=angular.noop,f.onaftersave=angular.noop}return n.$inject=["$scope","$attrs","$element","$parse","editableThemes","editableOptions","$rootScope","$compile","$q"],n}]),angular.module("xeditable").factory("editableDirectiveFactory",["$parse","$compile","editableThemes","$rootScope","$document","editableController","editableFormController",function(e,t,n,r,a,o,i){return function(t){return{restrict:"A",scope:!0,require:[t.directiveName,"?^form"],controller:o,link:function(n,o,s,l){var u,c=l[0],d=!1;if(l[1])u=l[1],d=!0;else if(s.eForm){var f=e(s.eForm)(n);if(f)u=f,d=!0;else for(var m=0;m=0&&e.splice(n,1),t},camelToDash:function(e){var t=/[A-Z]/g;return e.replace(t,function(e,t){return(t?"-":"")+e.toLowerCase()})},dashToCamel:function(e){var t=/([\:\-\_]+(.))/g,n=/^moz([A-Z])/;return e.replace(t,function(e,t,n,r){return r?n.toUpperCase():n}).replace(n,"Moz$1")}}}]),angular.module("xeditable").factory("editableNgOptionsParser",[function(){function e(e){var n;if(!(n=e.match(t)))throw"ng-options parse error";var r,a=n[2]||n[1],o=n[4]||n[6],i=n[5],s=(n[3],n[2]?n[1]:o),l=n[7],u=n[8],c=u?n[8]:null;return void 0===i?(r=o+" in "+l,void 0!==u&&(r+=" track by "+c)):r="("+i+", "+o+") in "+l,{ngRepeat:r,locals:{valueName:o,keyName:i,valueFn:s,displayFn:a}}}var t=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;return e}]),angular.module("xeditable").factory("editableThemes",function(){return{default:{formTpl:'
',noformTpl:'',controlsTpl:'',inputTpl:"",errorTpl:'
',buttonsTpl:'',submitTpl:'',cancelTpl:''},bs2:{formTpl:'
',noformTpl:'',controlsTpl:'
',inputTpl:"",errorTpl:'
',buttonsTpl:'',submitTpl:'',cancelTpl:''},bs3:{formTpl:'
',noformTpl:'',controlsTpl:'
',inputTpl:"",errorTpl:'
', +buttonsTpl:'',submitTpl:'',cancelTpl:'',buttonsClass:"",inputClass:"",postrender:function(){switch(this.directiveName){case"editableText":case"editableSelect":case"editableTextarea":case"editableEmail":case"editableTel":case"editableNumber":case"editableUrl":case"editableSearch":case"editableDate":case"editableDatetime":case"editableTime":case"editableMonth":case"editableWeek":if(this.inputEl.addClass("form-control"),this.theme.inputClass){if(this.inputEl.attr("multiple")&&("input-sm"===this.theme.inputClass||"input-lg"===this.theme.inputClass))break;this.inputEl.addClass(this.theme.inputClass)}}this.buttonsEl&&this.theme.buttonsClass&&this.buttonsEl.find("button").addClass(this.theme.buttonsClass)}}}}),function(e,t,n){"use strict";function r(e){return F(e)?e:Object.keys(e).map(function(t){return e[t]})}function a(e){return null===e}function o(e,t){return-1==Object.keys(e).map(function(r){return t[r]!==n&&t[r]==e[r]}).indexOf(!1)}function i(e,t){if(""===t)return e;var n=e.indexOf(t.charAt(0));return-1!==n&&i(e.substr(n+1),t.substr(1))}function s(e,t,n){var r=0;return e.filter(function(e){var a=D(n)?t>r&&n(e):t>r;return r=a?r+1:r,a})}function l(e,t,n){return n.round(e*n.pow(10,t))/n.pow(10,t)}function u(e,t,n){return t=t||[],Object.keys(e).forEach(function(r){if(T(e[r])&&!F(e[r])){var a=n?n+"."+r:n;u(e[r],t,a||r)}else{var o=n?n+"."+r:r;t.push(o)}}),t}function c(e){return e&&e.$evalAsync&&e.$watch}function d(){return function(e,t){return e>t}}function f(){return function(e,t){return e>=t}}function m(){return function(e,t){return t>e}}function p(){return function(e,t){return t>=e}}function b(){return function(e,t){return e==t}}function h(){return function(e,t){return e!=t}}function v(){return function(e,t){return e===t}}function g(){return function(e,t){return e!==t}}function _(e){return function(t,n){return t=T(t)?r(t):t,!(!F(t)||E(n))&&t.some(function(t){return T(t)||j(n)?e(n)(t):t===n})}}function $(e,t){return t=t||0,t>=e.length?e:F(e[t])?$(e.slice(0,t).concat(e[t],e.slice(t+1)),t):$(e,t+1)}function w(e){return function(t,n){function a(e,t){return!E(t)&&e.some(function(e){return N(e,t)})}if(t=T(t)?r(t):t,!F(t))return t;var o=[],i=e(n);return t.filter(E(n)?function(e,t,n){return n.indexOf(e)===t}:function(e){var t=i(e);return!a(o,t)&&(o.push(t),!0)})}}function y(e,t,n){return t?e+n+y(e,--t,n):e}var D=t.isDefined,E=t.isUndefined,j=t.isFunction,C=t.isString,R=t.isNumber,T=t.isObject,F=t.isArray,x=t.forEach,A=t.extend,S=t.copy,N=t.equals;String.prototype.contains||(String.prototype.contains=function(){return-1!==String.prototype.indexOf.apply(this,arguments)}),t.module("a8m.angular",[]).filter("isUndefined",function(){return function(e){return t.isUndefined(e)}}).filter("isDefined",function(){return function(e){return t.isDefined(e)}}).filter("isFunction",function(){return function(e){return t.isFunction(e)}}).filter("isString",function(){return function(e){return t.isString(e)}}).filter("isNumber",function(){return function(e){return t.isNumber(e)}}).filter("isArray",function(){return function(e){return t.isArray(e)}}).filter("isObject",function(){return function(e){return t.isObject(e)}}).filter("isEqual",function(){return function(e,n){return t.equals(e,n)}}),t.module("a8m.conditions",[]).filter({isGreaterThan:d,">":d,isGreaterThanOrEqualTo:f,">=":f,isLessThan:m,"<":m,isLessThanOrEqualTo:p,"<=":p,isEqualTo:b,"==":b,isNotEqualTo:h,"!=":h,isIdenticalTo:v,"===":v,isNotIdenticalTo:g,"!==":g}),t.module("a8m.is-null",[]).filter("isNull",function(){return function(e){return a(e)}}),t.module("a8m.after-where",[]).filter("afterWhere",function(){return function(e,t){if(e=T(e)?r(e):e,!F(e)||E(t))return e;var n=e.map(function(e){return o(t,e)}).indexOf(!0);return e.slice(-1===n?0:n)}}),t.module("a8m.after",[]).filter("after",function(){return function(e,t){return e=T(e)?r(e):e,F(e)?e.slice(t):e}}),t.module("a8m.before-where",[]).filter("beforeWhere",function(){return function(e,t){if(e=T(e)?r(e):e,!F(e)||E(t))return e;var n=e.map(function(e){return o(t,e)}).indexOf(!0);return e.slice(0,-1===n?e.length:++n)}}),t.module("a8m.before",[]).filter("before",function(){return function(e,t){return e=T(e)?r(e):e,F(e)?e.slice(0,t?--t:t):e}}),t.module("a8m.concat",[]).filter("concat",[function(){return function(e,t){if(E(t))return e;if(F(e))return e.concat(T(t)?r(t):t);if(T(e)){return r(e).concat(T(t)?r(t):t)}return e}}]),t.module("a8m.contains",[]).filter({contains:["$parse",_],some:["$parse",_]}),t.module("a8m.count-by",[]).filter("countBy",["$parse",function(e){return function(t,n){var a,o={},i=e(n);return t=T(t)?r(t):t,!F(t)||E(n)?t:(t.forEach(function(e){a=i(e),o[a]||(o[a]=0),o[a]++}),o)}}]),t.module("a8m.defaults",[]).filter("defaults",["$parse",function(e){return function(t,n){if(t=T(t)?r(t):t,!F(t)||!T(n))return t;var a=u(n);return t.forEach(function(t){a.forEach(function(r){var a=e(r),o=a.assign;E(a(t))&&o(t,a(n))})}),t}}]),t.module("a8m.every",[]).filter("every",["$parse",function(e){return function(t,n){return t=T(t)?r(t):t,!(F(t)&&!E(n))||t.every(function(t){return T(t)||j(n)?e(n)(t):t===n})}}]),t.module("a8m.filter-by",[]).filter("filterBy",["$parse",function(e){return function(t,a,o){var i;return o=C(o)||R(o)?String(o).toLowerCase():n,t=T(t)?r(t):t,!F(t)||E(o)?t:t.filter(function(t){return a.some(function(n){if(~n.indexOf("+")){var r=n.replace(new RegExp("\\s","g"),"").split("+");i=r.reduce(function(n,r,a){return 1===a?e(n)(t)+" "+e(r)(t):n+" "+e(r)(t)})}else i=e(n)(t);return!(!C(i)&&!R(i))&&String(i).toLowerCase().contains(o)})})}}]),t.module("a8m.first",[]).filter("first",["$parse",function(e){return function(t){var a,o,i;return t=T(t)?r(t):t,F(t)?(i=Array.prototype.slice.call(arguments,1),a=R(i[0])?i[0]:1,o=R(i[0])?R(i[1])?n:i[1]:i[0],i.length?s(t,a,o?e(o):o):t[0]):t}}]),t.module("a8m.flatten",[]).filter("flatten",function(){return function(e,t){return t=t||!1,e=T(e)?r(e):e,F(e)?t?[].concat.apply([],e):$(e,0):e}}),t.module("a8m.fuzzy-by",[]).filter("fuzzyBy",["$parse",function(e){return function(t,n,a,o){var s,l,u=o||!1;return t=T(t)?r(t):t,!F(t)||E(n)||E(a)?t:(l=e(n),t.filter(function(e){return s=l(e),!!C(s)&&(s=u?s:s.toLowerCase(),a=u?a:a.toLowerCase(),!1!==i(s,a))}))}}]),t.module("a8m.fuzzy",[]).filter("fuzzy",function(){return function(e,t,n){function a(e,t){var n,r;return 0=0&&R(t)&&isFinite(t)?1024>t?l(t,n,e)+" B":1048576>t?l(t/1024,n,e)+" KB":1073741824>t?l(t/1048576,n,e)+" MB":l(t/1073741824,n,e)+" GB":"NaN"}}]),t.module("a8m.math.degrees",["a8m.math"]).filter("degrees",["$math",function(e){return function(t,n){if(R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)){var r=180*t/e.PI;return e.round(r*e.pow(10,n))/e.pow(10,n)}return"NaN"}}]),t.module("a8m.math.kbFmt",["a8m.math"]).filter("kbFmt",["$math",function(e){return function(t,n){return R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)?1024>t?l(t,n,e)+" KB":1048576>t?l(t/1024,n,e)+" MB":l(t/1048576,n,e)+" GB":"NaN"}}]),t.module("a8m.math",[]).factory("$math",["$window",function(e){return e.Math}]),t.module("a8m.math.max",["a8m.math"]).filter("max",["$math","$parse",function(e,t){function n(n,r){var a=n.map(function(e){return t(r)(e)});return a.indexOf(e.max.apply(e,a))}return function(t,r){return F(t)?E(r)?e.max.apply(e,t):t[n(t,r)]:t}}]),t.module("a8m.math.min",["a8m.math"]).filter("min",["$math","$parse",function(e,t){function n(n,r){var a=n.map(function(e){return t(r)(e)});return a.indexOf(e.min.apply(e,a))}return function(t,r){return F(t)?E(r)?e.min.apply(e,t):t[n(t,r)]:t}}]),t.module("a8m.math.percent",["a8m.math"]).filter("percent",["$math","$window",function(e,t){return function(n,r,a){var o=C(n)?t.Number(n):n;return r=r||100,a=a||!1,!R(o)||t.isNaN(o)?n:a?e.round(o/r*100):o/r*100}}]),t.module("a8m.math.radians",["a8m.math"]).filter("radians",["$math",function(e){return function(t,n){if(R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)){var r=3.14159265359*t/180;return e.round(r*e.pow(10,n))/e.pow(10,n)}return"NaN"}}]),t.module("a8m.math.radix",[]).filter("radix",function(){return function(e,t){var n=/^[2-9]$|^[1-2]\d$|^3[0-6]$/;return R(e)&&n.test(t)?e.toString(t).toUpperCase():e}}),t.module("a8m.math.shortFmt",["a8m.math"]).filter("shortFmt",["$math",function(e){return function(t,n){return R(n)&&isFinite(n)&&n%1==0&&n>=0&&R(t)&&isFinite(t)?1e3>t?t:1e6>t?l(t/1e3,n,e)+" K":1e9>t?l(t/1e6,n,e)+" M":l(t/1e9,n,e)+" B":"NaN"}}]),t.module("a8m.math.sum",[]).filter("sum",function(){return function(e,t){return F(e)?e.reduce(function(e,t){return e+t},t||0):e}}),t.module("a8m.ends-with",[]).filter("endsWith",function(){return function(e,t,n){var r,a=n||!1;return!C(e)||E(t)?e:(e=a?e:e.toLowerCase(),r=e.length-t.length,-1!==e.indexOf(a?t:t.toLowerCase(),r))}}),t.module("a8m.latinize",[]).filter("latinize",[function(){function e(e){return e.replace(/[^\u0000-\u007E]/g,function(e){return n[e]||e})}for(var t=[{base:"A",letters:"AⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ"},{base:"AA",letters:"Ꜳ"},{base:"AE",letters:"ÆǼǢ"},{base:"AO",letters:"Ꜵ"},{base:"AU",letters:"Ꜷ"},{base:"AV",letters:"ꜸꜺ"},{base:"AY",letters:"Ꜽ"},{base:"B",letters:"BⒷBḂḄḆɃƂƁ"},{base:"C",letters:"CⒸCĆĈĊČÇḈƇȻꜾ"},{base:"D",letters:"DⒹDḊĎḌḐḒḎĐƋƊƉꝹ"},{base:"DZ",letters:"DZDŽ"},{base:"Dz",letters:"DzDž"},{base:"E",letters:"EⒺEÈÉÊỀẾỄỂẼĒḔḖĔĖËẺĚȄȆẸỆȨḜĘḘḚƐƎ"},{base:"F",letters:"FⒻFḞƑꝻ"},{base:"G",letters:"GⒼGǴĜḠĞĠǦĢǤƓꞠꝽꝾ"},{base:"H",letters:"HⒽHĤḢḦȞḤḨḪĦⱧⱵꞍ"},{base:"I",letters:"IⒾIÌÍÎĨĪĬİÏḮỈǏȈȊỊĮḬƗ"},{base:"J",letters:"JⒿJĴɈ"},{base:"K",letters:"KⓀKḰǨḲĶḴƘⱩꝀꝂꝄꞢ"},{base:"L",letters:"LⓁLĿĹĽḶḸĻḼḺŁȽⱢⱠꝈꝆꞀ"},{base:"LJ",letters:"LJ"},{base:"Lj",letters:"Lj"},{base:"M",letters:"MⓂMḾṀṂⱮƜ"},{base:"N",letters:"NⓃNǸŃÑṄŇṆŅṊṈȠƝꞐꞤ"},{base:"NJ",letters:"NJ"},{base:"Nj",letters:"Nj"},{base:"O",letters:"OⓄOÒÓÔỒỐỖỔÕṌȬṎŌṐṒŎȮȰÖȪỎŐǑȌȎƠỜỚỠỞỢỌỘǪǬØǾƆƟꝊꝌ"},{base:"OI",letters:"Ƣ"},{base:"OO",letters:"Ꝏ"},{base:"OU",letters:"Ȣ"},{base:"OE",letters:"ŒŒ"},{base:"oe",letters:"œœ"},{base:"P",letters:"PⓅPṔṖƤⱣꝐꝒꝔ"},{base:"Q",letters:"QⓆQꝖꝘɊ"},{base:"R",letters:"RⓇRŔṘŘȐȒṚṜŖṞɌⱤꝚꞦꞂ"},{base:"S",letters:"SⓈSẞŚṤŜṠŠṦṢṨȘŞⱾꞨꞄ"},{base:"T",letters:"TⓉTṪŤṬȚŢṰṮŦƬƮȾꞆ"},{base:"TZ",letters:"Ꜩ"},{base:"U",letters:"UⓊUÙÚÛŨṸŪṺŬÜǛǗǕǙỦŮŰǓȔȖƯỪỨỮỬỰỤṲŲṶṴɄ"},{base:"V",letters:"VⓋVṼṾƲꝞɅ"},{base:"VY",letters:"Ꝡ"},{base:"W",letters:"WⓌWẀẂŴẆẄẈⱲ"},{base:"X",letters:"XⓍXẊẌ"},{base:"Y",letters:"YⓎYỲÝŶỸȲẎŸỶỴƳɎỾ"},{base:"Z",letters:"ZⓏZŹẐŻŽẒẔƵȤⱿⱫꝢ"},{base:"a",letters:"aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐ"},{base:"aa",letters:"ꜳ"},{base:"ae",letters:"æǽǣ"},{base:"ao",letters:"ꜵ"},{base:"au",letters:"ꜷ"},{base:"av",letters:"ꜹꜻ"},{base:"ay",letters:"ꜽ"},{base:"b",letters:"bⓑbḃḅḇƀƃɓ"},{base:"c",letters:"cⓒcćĉċčçḉƈȼꜿↄ"},{base:"d",letters:"dⓓdḋďḍḑḓḏđƌɖɗꝺ"},{base:"dz",letters:"dzdž"},{base:"e",letters:"eⓔeèéêềếễểẽēḕḗĕėëẻěȅȇẹệȩḝęḙḛɇɛǝ"},{base:"f",letters:"fⓕfḟƒꝼ"},{base:"g",letters:"gⓖgǵĝḡğġǧģǥɠꞡᵹꝿ"},{base:"h",letters:"hⓗhĥḣḧȟḥḩḫẖħⱨⱶɥ"},{base:"hv",letters:"ƕ"},{base:"i",letters:"iⓘiìíîĩīĭïḯỉǐȉȋịįḭɨı"},{base:"j",letters:"jⓙjĵǰɉ"},{base:"k",letters:"kⓚkḱǩḳķḵƙⱪꝁꝃꝅꞣ"},{base:"l",letters:"lⓛlŀĺľḷḹļḽḻſłƚɫⱡꝉꞁꝇ"},{base:"lj",letters:"lj"},{base:"m",letters:"mⓜmḿṁṃɱɯ"},{base:"n",letters:"nⓝnǹńñṅňṇņṋṉƞɲʼnꞑꞥ"},{base:"nj",letters:"nj"},{base:"o",letters:"oⓞoòóôồốỗổõṍȭṏōṑṓŏȯȱöȫỏőǒȍȏơờớỡởợọộǫǭøǿɔꝋꝍɵ"},{base:"oi",letters:"ƣ"},{base:"ou",letters:"ȣ"},{base:"oo",letters:"ꝏ"},{base:"p",letters:"pⓟpṕṗƥᵽꝑꝓꝕ"},{base:"q",letters:"qⓠqɋꝗꝙ"},{base:"r",letters:"rⓡrŕṙřȑȓṛṝŗṟɍɽꝛꞧꞃ"},{base:"s",letters:"sⓢsßśṥŝṡšṧṣṩșşȿꞩꞅẛ"},{base:"t",letters:"tⓣtṫẗťṭțţṱṯŧƭʈⱦꞇ"},{base:"tz",letters:"ꜩ"},{base:"u",letters:"uⓤuùúûũṹūṻŭüǜǘǖǚủůűǔȕȗưừứữửựụṳųṷṵʉ"},{base:"v",letters:"vⓥvṽṿʋꝟʌ"},{base:"vy",letters:"ꝡ"},{base:"w",letters:"wⓦwẁẃŵẇẅẘẉⱳ"},{base:"x",letters:"xⓧxẋẍ"},{base:"y",letters:"yⓨyỳýŷỹȳẏÿỷẙỵƴɏỿ"},{base:"z",letters:"zⓩzźẑżžẓẕƶȥɀⱬꝣ"}],n={},r=0;r<]*>/g,""):e}}),t.module("a8m.test",[]).filter("test",function(){return function(e,t,n){var r=new RegExp(t,n);return C(e)?r.test(e):e}}),t.module("a8m.trim",[]).filter("trim",function(){return function(e,t){var n=t||"\\s";return C(e)?e.replace(new RegExp("^"+n+"+|"+n+"+$","g"),""):e}}),t.module("a8m.truncate",[]).filter("truncate",function(){return function(e,t,n,r){return t=E(t)?e.length:t,r=r||!1,n=n||"",!C(e)||e.length<=t?e:e.substring(0,r?-1===e.indexOf(" ",t)?e.length:e.indexOf(" ",t):t)+n}}),t.module("a8m.ucfirst",[]).filter("ucfirst",[function(){return function(e){return C(e)?e.split(" ").map(function(e){return e.charAt(0).toUpperCase()+e.substring(1)}).join(" "):e}}]),t.module("a8m.uri-component-encode",[]).filter("uriComponentEncode",["$window",function(e){return function(t){return C(t)?e.encodeURIComponent(t):t}}]),t.module("a8m.uri-encode",[]).filter("uriEncode",["$window",function(e){return function(t){return C(t)?e.encodeURI(t):t}}]),t.module("a8m.wrap",[]).filter("wrap",function(){return function(e,t,n){return C(e)&&D(t)?[t,e,n||t].join(""):e}}),t.module("a8m.filter-watcher",[]).provider("filterWatcher",function(){this.$get=["$window","$rootScope",function(e,n){function r(e,n){return[e,t.toJson(n)].join("#").replace(/"/g,"")}function a(e){var t=e.targetScope.$id;x(d[t],function(e){delete u[e]}),delete d[t]}function o(){f(function(){n.$$phase||(u={})})}function i(e,t){var n=e.$id;return E(d[n])&&(e.$on("$destroy",a),d[n]=[]),d[n].push(t)}function s(e,t){var n=r(e,t);return u[n]}function l(e,t,n,a){var s=r(e,t);return u[s]=a,c(n)?i(n,s):o(),a}var u={},d={},f=e.setTimeout;return{isMemoized:s,memoize:l}}]}),t.module("angular.filter",["a8m.ucfirst","a8m.uri-encode","a8m.uri-component-encode","a8m.slugify","a8m.latinize","a8m.strip-tags","a8m.stringular","a8m.truncate","a8m.starts-with","a8m.ends-with","a8m.wrap","a8m.trim","a8m.ltrim","a8m.rtrim","a8m.repeat","a8m.test","a8m.match","a8m.to-array","a8m.concat","a8m.contains","a8m.unique","a8m.is-empty","a8m.after","a8m.after-where","a8m.before","a8m.before-where","a8m.defaults","a8m.where","a8m.reverse","a8m.remove","a8m.remove-with","a8m.group-by","a8m.count-by","a8m.search-field","a8m.fuzzy-by","a8m.fuzzy","a8m.omit","a8m.pick","a8m.every","a8m.filter-by","a8m.xor","a8m.map","a8m.first","a8m.last","a8m.flatten","a8m.join","a8m.math","a8m.math.max","a8m.math.min","a8m.math.percent","a8m.math.radix","a8m.math.sum","a8m.math.degrees","a8m.math.radians","a8m.math.byteFmt","a8m.math.kbFmt","a8m.math.shortFmt","a8m.angular","a8m.conditions","a8m.is-null","a8m.filter-watcher"])}(window,window.angular),define("job-roles/modules/job-roles.core",["common/angular","common/ui-select","common/directives/angular-date/date-input","common/modules/directives","common/modules/routers/compu-ng-route","common/filters/angular-date/format-date","common/services/angular-date/date-format","common/services/crm-ang.service","common/services/dom-event-trigger","common/services/pub-sub","job-roles/vendor/angular-editable","job-roles/vendor/angular-filter"],function(e){"use strict";e.module("hrjobroles.core",["angular.filter","ngAnimate","ngSanitize","ngResource","ui.bootstrap","ui.select","xeditable","common.angularDate","common.directives","common.services","compuNgRoute"])}),define("job-roles/filters/get-active-values.filter",["common/lodash"],function(e){"use strict";function t(t){return t.debug("Filter: getActiveValues"),function(t){var n={};return e.each(t,function(e,t){"1"===e.is_active&&(n[t]=e)}),n}}return t.__name="getActiveValues",t.$inject=["$log"],t}),define("job-roles/modules/job-roles.filters",["common/angular","job-roles/filters/get-active-values.filter"],function(e,t){"use strict";return e.module("hrjobroles.filters",[]).filter(t.__name,t)}),define("job-roles/modules/job-roles.run",["common/angular"],function(e){"use strict";function t(e,t,n,r){n.theme="bs3",t.contactId=r.contactId,t.pathBaseUrl=r.pathBaseUrl,t.pathTpl=r.pathTpl,t.pathIncludeTpl=r.pathIncludeTpl,t.prefix=r.classNamePrefix}e.module("hrjobroles.run",["hrjobroles.constants"]).run(t),t.$inject=["$q","$rootScope","editableOptions","settings"]}),define("job-roles/services/date-validation.service",["common/moment"],function(e){function t(t){function n(e,t){e.isValid()||l("Date is not valid!!",t)}function r(e,t){e.isSameOrAfter(t)&&l("Start Date cannot be the same as or after the End Date.",["start_date","end_date"])}function a(e,t){e.isBefore(t)&&l("Start Date cannot be lower than Contract Start Date.",["start_date"])}function o(e,t){e.isAfter(t)&&l("Start Date cannot be higher than Contract End Date.",["start_date"])}function i(e,t){e.isAfter(t)&&l("End Date cannot be higher than Contract End Date.",["end_date"])}function s(t,n){return t instanceof Date&&(t=e(t).valueOf()),e(t,n,!0).startOf("day")}var l=function(e,t){throw new Error(e,t[0])},u={dateFormats:["x","YYYY-MM-DD"],setErrorCallback:function(e){if("function"!=typeof e)throw new TypeError("Error callback must be a function.");l=e},validate:function(e,t,l,u){e=s(e,this.dateFormats),l=s(l,this.dateFormats),u=s(u,this.dateFormats),n(e,["start_date"]),o(e,u),a(e,l),(0===t||t)&&(t=s(t,this.dateFormats),n(t,["end_date"]),i(t,u),r(e,t))}};return t.DATE_FORMAT&&u.dateFormats.push(t.DATE_FORMAT.toUpperCase()),u}return t.__name="dateValidation",t.$inject=["HR_settings"],t}),define("job-roles/services/filters.service",[],function(){"use strict";function e(){return{isNotUndefined:function(e){try{return e.constructor===Array?e.filter(function(e){return"undefined"!==e&&void 0!==e}):e}catch(t){return e}},issetCostCentre:function(e){try{return e.constructor===Array?e.filter(function(e){return""!==e.cost_centre_id&&("1"===e.type&&parseInt(e.percentage)>0||"0"===e.type&&parseInt(e.amount)>0)}):e}catch(t){return e}},issetFunder:function(e){try{return e.constructor===Array?e.filter(function(e){return""!==e.funder_id&&("1"===e.type&&parseInt(e.percentage)>0||"0"===e.type&&parseInt(e.amount)>0)}):e}catch(t){return e}}}}return e.__name="filtersService",e}),define("job-roles/services/job-role.service",["common/lodash"],function(e){"use strict";function t(t,n,r){function a(n){var r=n["api.HRJobContractRevision.get"].values;delete n["api.HRJobContractRevision.get"],n.revisions=e.compact(r.map(function(e){var r=e["api.HRJobDetails.getsingle"];return r.period_start_date===n.period_start_date&&r.period_end_date===n.period_end_date?null:(r.period_start_date=t("formatDate")(r.period_start_date),r.period_end_date=t("formatDate")(r.period_end_date),r)}))}return{getContracts:function(e){var t=r.defer();return CRM.api3("HRJobContract","get",{sequential:1,contact_id:e,deleted:0,return:"title,period_end_date,period_start_date","api.HRJobContractRevision.get":{jobcontract_id:"$value.id","api.HRJobDetails.getsingle":{jobcontract_revision_id:"$value.id"}}}).done(function(e){e.values.forEach(a),t.resolve(e)}).error(function(){t.reject("An error occured while fetching items")}),t.promise},getAllJobRoles:function(e){var t=r.defer();return CRM.api3("HrJobRoles","get",{sequential:1,return:"id,job_contract_id,title,description,status,funder,funder_val_type,percent_pay_funder,amount_pay_funder,cost_center,cost_center_val_type,percent_pay_cost_center,amount_pay_cost_center,level_type,location,region,department,end_date,start_date",job_contract_id:{IN:e}}).done(function(e){t.resolve(e)}).error(function(e){t.reject("An error occured while fetching items")}),t.promise},deleteJobRole:function(e){var t=r.defer();return CRM.api3("HrJobRoles","delete",{sequential:1,id:e}).done(function(e){t.resolve(e)}).error(function(e){t.reject("An error occured while deleting items")}),t.promise},createJobRole:function(e){var t="|",n="|",a="|",o="|",i="|",s="|",l="|",u="|";if(void 0!==e.funders)for(var c=0,d=e.funders.length;c
- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
diff --git a/com.civicrm.hrjobroles/views/include/job_role_panel.html b/com.civicrm.hrjobroles/views/include/job_role_panel.html index 07be3feac3d..0ed4738f9e3 100755 --- a/com.civicrm.hrjobroles/views/include/job_role_panel.html +++ b/com.civicrm.hrjobroles/views/include/job_role_panel.html @@ -158,17 +158,24 @@ {{jobroles.LocationsData[jobroles.editData[job_roles_data.id]['location']]['title'] || '-'}}

- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
@@ -181,17 +188,24 @@ {{jobroles.RegionsData[jobroles.editData[job_roles_data.id]['region']]['title'] || '-'}}

- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
@@ -204,17 +218,24 @@ {{jobroles.DepartmentsData[jobroles.editData[job_roles_data.id]['department']]['title'] || '-'}}

- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
@@ -227,17 +248,24 @@ {{jobroles.LevelsData[jobroles.editData[job_roles_data.id]['level']]['title'] || '-'}}

- - {{$select.selected.value.title}} - -
-
-
+
+
+ + {{$select.selected.value.title}} + +
+
+
+
+ + + +
diff --git a/contactaccessrights/info.xml b/contactaccessrights/info.xml index bcf188ba4ee..91804b6cf8e 100644 --- a/contactaccessrights/info.xml +++ b/contactaccessrights/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/contactsummary/css/contactsummary.css b/contactsummary/css/contactsummary.css index 8ff08c076f6..6c1a21f49ef 100644 --- a/contactsummary/css/contactsummary.css +++ b/contactsummary/css/contactsummary.css @@ -1 +1,5 @@ +<<<<<<< HEAD #bootstrap-theme .leave-widget h4{color:#4D4D69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px}#bootstrap-theme .leave-widget__types>table,#bootstrap-theme .leave-widget__sickness>table,#bootstrap-theme .leave-widget__next-leave>table{border:none}#bootstrap-theme .leave-widget__types>table thead tr th,#bootstrap-theme .leave-widget__sickness>table thead tr th,#bootstrap-theme .leave-widget__next-leave>table thead tr th{color:#4D4D69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px;background:none;width:35%}#bootstrap-theme .leave-widget__types>table thead tr th:first-child,#bootstrap-theme .leave-widget__sickness>table thead tr th:first-child,#bootstrap-theme .leave-widget__next-leave>table thead tr th:first-child{width:65%}#bootstrap-theme .leave-widget__types>table tbody tr td,#bootstrap-theme .leave-widget__sickness>table tbody tr td,#bootstrap-theme .leave-widget__next-leave>table tbody tr td{color:#0071BD;font-size:16px;font-weight:600;padding-bottom:9px}#bootstrap-theme .leave-widget__types>table tbody tr td:first-child,#bootstrap-theme .leave-widget__sickness>table tbody tr td:first-child,#bootstrap-theme .leave-widget__next-leave>table tbody tr td:first-child{color:#464354}#bootstrap-theme .leave-widget hr{border-color:#DEE4ED;margin-bottom:25px;margin-top:25px}#bootstrap-theme .leave-widget__sickness h4{margin-top:18px}#bootstrap-theme .leave-widget__next-leave h3{font-size:16px;margin-bottom:16px;margin-top:0}#bootstrap-theme .leave-widget__next-leave__deduction{font-size:16px;font-weight:600;color:#464354}#bootstrap-theme .date-range-calendar{font-size:13px;font-weight:normal}#bootstrap-theme .date-range-calendar__from,#bootstrap-theme .date-range-calendar__to{float:left;margin-bottom:10px}#bootstrap-theme .date-range-calendar__to::before{content:'\f178';float:left;font-size:16px;font-family:'FontAwesome';line-height:21px;margin:10px;margin-left:16px}#bootstrap-theme .date-range-calendar__day{background:#E8EEF0;border:1px solid #DEE4ED;border-radius:2px;border-top:none;display:inline-block;float:left;font-size:18px;height:40px;line-height:32px;margin-right:10px;text-align:center;width:40px}#bootstrap-theme .date-range-calendar__day::before{border-top:8px solid #0071BD;border-top-left-radius:2px;border-top-right-radius:2px;content:'';display:block;margin:-1px;width:calc(100% + 2px)}#bootstrap-theme .date-range-calendar__time{display:block}#bootstrap-theme button.info-button{background:none;border:none}#bootstrap-theme button.info-button .fa{color:#0071BD}#bootstrap-theme ul.week-heatmap{font-size:0;list-style:none;padding:0}#bootstrap-theme ul.week-heatmap li{background-color:#44CB7E;border-radius:2px;display:inline-block;font-size:16px;font-weight:600;height:40px;line-height:40px;margin-bottom:10px;margin-right:10px;text-align:center;width:40px}#bootstrap-theme ul.week-heatmap li.week-heatmap__medium{background-color:#E6AB5E}#bootstrap-theme ul.week-heatmap li.week-heatmap__high{color:#fff;background-color:#CF3458}#bootstrap-theme ul.week-heatmap li.week-heatmap__disabled{background-color:#E8EEF0;color:#464354}#contactsummary .panel--key-dates>.panel-body{padding-bottom:0;padding-top:0}#contactsummary .panel--key-details{margin-bottom:0 !important} +======= +#bootstrap-theme .leave-widget h4{color:#4d4d69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px}#bootstrap-theme .leave-widget__types>table,#bootstrap-theme .leave-widget__sickness>table,#bootstrap-theme .leave-widget__next-leave>table{border:none}#bootstrap-theme .leave-widget__types>table thead tr th,#bootstrap-theme .leave-widget__sickness>table thead tr th,#bootstrap-theme .leave-widget__next-leave>table thead tr th{color:#4d4d69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px;background:none;width:35%}#bootstrap-theme .leave-widget__types>table thead tr th:first-child,#bootstrap-theme .leave-widget__sickness>table thead tr th:first-child,#bootstrap-theme .leave-widget__next-leave>table thead tr th:first-child{width:65%}#bootstrap-theme .leave-widget__types>table tbody tr td,#bootstrap-theme .leave-widget__sickness>table tbody tr td,#bootstrap-theme .leave-widget__next-leave>table tbody tr td{color:#0071bd;font-size:16px;font-weight:600;padding-bottom:9px}#bootstrap-theme .leave-widget__types>table tbody tr td:first-child,#bootstrap-theme .leave-widget__sickness>table tbody tr td:first-child,#bootstrap-theme .leave-widget__next-leave>table tbody tr td:first-child{color:#464354}#bootstrap-theme .leave-widget hr{border-color:#DEE4ED;margin-bottom:25px;margin-top:25px}#bootstrap-theme .leave-widget__sickness h4{margin-top:18px}#bootstrap-theme .leave-widget__next-leave h3{font-size:16px;margin-bottom:16px;margin-top:0}#bootstrap-theme .leave-widget__next-leave__deduction{font-size:16px;font-weight:600;color:#464354}#bootstrap-theme .date-range-calendar{font-size:13px;font-weight:normal}#bootstrap-theme .date-range-calendar__from,#bootstrap-theme .date-range-calendar__to{float:left;margin-bottom:10px}#bootstrap-theme .date-range-calendar__to::before{content:'\f178';float:left;font-size:16px;font-family:'FontAwesome';line-height:21px;margin:10px;margin-left:16px}#bootstrap-theme .date-range-calendar__day{background:#e8eef0;border:1px solid #DEE4ED;border-radius:2px;border-top:none;display:inline-block;float:left;font-size:18px;height:40px;line-height:32px;margin-right:10px;text-align:center;width:40px}#bootstrap-theme .date-range-calendar__day::before{border-top:8px solid #0071bd;border-top-left-radius:2px;border-top-right-radius:2px;content:'';display:block;margin:-1px;width:calc(100% + 2px)}#bootstrap-theme .date-range-calendar__time{display:block}#bootstrap-theme button.info-button{background:none;border:none}#bootstrap-theme button.info-button .fa{color:#0071bd}#bootstrap-theme ul.week-heatmap{font-size:0;list-style:none;padding:0}#bootstrap-theme ul.week-heatmap li{background-color:#44cb7e;border-radius:2px;display:inline-block;font-size:16px;font-weight:600;height:40px;line-height:40px;margin-bottom:10px;margin-right:10px;text-align:center;width:40px}#bootstrap-theme ul.week-heatmap li.week-heatmap__medium{background-color:#e6ab5e}#bootstrap-theme ul.week-heatmap li.week-heatmap__high{color:#fff;background-color:#cf3458}#bootstrap-theme ul.week-heatmap li.week-heatmap__disabled{background-color:#e8eef0;color:#464354}#contactsummary{padding:20px}#contactsummary .panel--key-dates>.panel-body{padding-bottom:0;padding-top:0}#contactsummary .panel--key-details{margin-bottom:0 !important} +>>>>>>> PCHR-3426: Change the mobile layout diff --git a/contactsummary/info.xml b/contactsummary/info.xml index c520647e0ad..e5e1fe90a3b 100644 --- a/contactsummary/info.xml +++ b/contactsummary/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/contactsummary/scss/contactsummary.scss b/contactsummary/scss/contactsummary.scss index ed670166559..4904d580fb9 100644 --- a/contactsummary/scss/contactsummary.scss +++ b/contactsummary/scss/contactsummary.scss @@ -1,14 +1,14 @@ -@import "SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/overrides/variables"; -@import "SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/variables"; +@import 'SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/overrides/variables'; +@import 'SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/variables'; #bootstrap-theme { - @import "SCSSROOT/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/leave-widget"; - @import "./components/*"; + @import 'SCSSROOT/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/leave-widget'; + @import './components/*'; } +/* stylelint-disable selector-max-id */ #contactsummary { .panel--key-dates { - > .panel-body { padding-bottom: 0; padding-top: 0; @@ -19,3 +19,4 @@ margin-bottom: 0 !important; } } +/* stylelint-enable */ diff --git a/hrbank/info.xml b/hrbank/info.xml index 728ab44bba7..ed780473a44 100644 --- a/hrbank/info.xml +++ b/hrbank/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrcareer/info.xml b/hrcareer/info.xml index 6e41e7ba2ff..21310fadf93 100644 --- a/hrcareer/info.xml +++ b/hrcareer/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrcase/info.xml b/hrcase/info.xml index ab47c570dc6..4d274954e41 100644 --- a/hrcase/info.xml +++ b/hrcase/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrdemog/CRM/HRDemog/Upgrader.php b/hrdemog/CRM/HRDemog/Upgrader.php index 4a61caf1926..e32e54c4e78 100644 --- a/hrdemog/CRM/HRDemog/Upgrader.php +++ b/hrdemog/CRM/HRDemog/Upgrader.php @@ -161,4 +161,25 @@ public function upgrade_1400() { CRM_Core_DAO::executeQuery("UPDATE civicrm_custom_group SET is_reserved = 0, collapse_display = 1 where name = 'Extended_Demographics'"); return TRUE; } + + /** + * Upgrade CustomGroup, setting Extended_Demographics is_reserved value to YES + * + * @return bool + */ + public function upgrade_1401() { + $result = civicrm_api3('CustomGroup', 'get', [ + 'sequential' => 1, + 'return' => ['id'], + 'name' => 'Extended_Demographics', + ]); + + civicrm_api3('CustomGroup', 'create', [ + 'id' => $result['id'], + 'is_reserved' => 1, + ]); + + return TRUE; + } + } diff --git a/hrdemog/info.xml b/hrdemog/info.xml index 2bb05c6e9b0..20aba3312d5 100644 --- a/hrdemog/info.xml +++ b/hrdemog/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrident/CRM/HRIdent/Upgrader.php b/hrident/CRM/HRIdent/Upgrader.php index dd45de20b7e..f52db740561 100755 --- a/hrident/CRM/HRIdent/Upgrader.php +++ b/hrident/CRM/HRIdent/Upgrader.php @@ -135,4 +135,5 @@ public function upgrade_1501() { return true; } + } diff --git a/hrim/info.xml b/hrim/info.xml index 8909e6cccaf..877fcc16b88 100644 --- a/hrim/info.xml +++ b/hrim/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrjobcontract/CRM/Hrjobcontract/Page/View/Summary.tpl b/hrjobcontract/CRM/Hrjobcontract/Page/View/Summary.tpl index ad812c53eda..a48f5138c65 100644 --- a/hrjobcontract/CRM/Hrjobcontract/Page/View/Summary.tpl +++ b/hrjobcontract/CRM/Hrjobcontract/Page/View/Summary.tpl @@ -49,7 +49,7 @@ {* CRM-12735 - Conditionally include the Actions and Edit buttons if contact is NOT in trash.*} {if !$isDeleted} - {if call_user_func(array('CRM_Core_Permission','check'), 'access CiviCRM')} + {if $canAccessCiviCRM }
  • {include file="CRM/Contact/Page/Inline/Actions.tpl"}
  • diff --git a/hrjobcontract/CRM/Hrjobcontract/Upgrader.php b/hrjobcontract/CRM/Hrjobcontract/Upgrader.php index 50b323a33dc..a858562a875 100755 --- a/hrjobcontract/CRM/Hrjobcontract/Upgrader.php +++ b/hrjobcontract/CRM/Hrjobcontract/Upgrader.php @@ -165,7 +165,7 @@ public function upgradeBundle() { ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 "); CRM_Core_DAO::executeQuery(" - INSERT INTO `civicrm_hrhours_location` (`id`, `location`, `standard_hours`, `periodicity`, `is_active`) + INSERT INTO `civicrm_hrhours_location` (`id`, `location`, `standard_hours`, `periodicity`, `is_active`) VALUES (1, 'Head office', 40, 'Week', 1) "); @@ -512,6 +512,9 @@ public function upgradeBundle() { $this->upgrade_1030(); $this->upgrade_1032(); $this->upgrade_1033(); + $this->upgrade_1034(); + $this->upgrade_1035(); + $this->upgrade_1036(); } function upgrade_1001() { @@ -925,7 +928,7 @@ function upgrade_1020() { if (empty($data)) { CRM_Core_DAO::executeQuery(" - INSERT INTO `civicrm_hrpay_scale` (`pay_scale`, `pay_grade`, `currency`, `amount`, `periodicity`, `is_active`) + INSERT INTO `civicrm_hrpay_scale` (`pay_scale`, `pay_grade`, `currency`, `amount`, `periodicity`, `is_active`) VALUES ('Not Applicable', NULL, NULL, NULL, NULL, 1) "); } @@ -1007,8 +1010,8 @@ public function upgrade_1025() { */ public function upgrade_1026() { $query = " - ALTER TABLE `civicrm_hrjobcontract_hour` - CHANGE `fte_num` `fte_num` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT '.', + ALTER TABLE `civicrm_hrjobcontract_hour` + CHANGE `fte_num` `fte_num` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT '.', CHANGE `fte_denom` `fte_denom` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT '.' "; CRM_Core_DAO::executeQuery($query); @@ -1157,6 +1160,135 @@ public function upgrade_1033() { return TRUE; } + /** + * Update CustomGroup, setting Contact_Length_Of_Service is_reserved to Yes + * + * @return bool + */ + public function upgrade_1034() { + $result = civicrm_api3('CustomGroup', 'get', [ + 'sequential' => 1, + 'return' => ['id'], + 'name' => 'Contact_Length_Of_Service', + ]); + + civicrm_api3('CustomGroup', 'create', [ + 'id' => $result['id'], + 'is_reserved' => 1, + ]); + + return TRUE; + } + + /** + * Upgrade CustomGroup, setting HRJobContract_Dates, HRJob_Summary and + * HRJobContract_Summary is_reserved value to Yes if it is existing. + * + * @return bool + */ + public function upgrade_1035() { + $customGroups = [ + 'HRJobContract_Dates', + 'HRJob_Summary', + 'HRJobContract_Summary' + ]; + + $result = civicrm_api3('CustomGroup', 'get', [ + 'return' => ['id', 'name'], + 'name' => ['IN' => $customGroups], + ]); + + if ($result['count'] > 0) { + foreach ($result['values'] as $value) { + $params = ['id' => $value['id'], 'is_reserved' => 1]; + + /** + * 'is_multiple' is added to prevent bug that changes it to false + * @see https://issues.civicrm.org/jira/browse/CRM-21853 + */ + if ($value['name'] === 'HRJobContract_Dates') { + $params['is_multiple'] = 1; + } + + civicrm_api3('CustomGroup', 'create', $params); + } + } + + return TRUE; + } + + /** + * Adds a submenu containing links to edit job contract option groups + * + * @return bool + */ + public function upgrade_1036() { + $domain = CRM_Core_Config::domainID(); + $params = ['return' => 'id', 'name' => 'Administer', 'domain_id' => $domain]; + $administerId = (int) civicrm_api3('Navigation', 'getvalue', $params); + + $permission = 'access CiviCRM'; + $parent = $this->createNavItem('Job Contract', $permission, $administerId); + $parentId = $parent['id']; + + // Weight cannot be set when creating for the first time + civicrm_api3('Navigation', 'create', ['id' => $parentId, 'weight' => -100]); + + // If we don't flush it will not recognize newly created parent_id + CRM_Core_PseudoConstant::flush(); + + // returns the link to an option group edit page + $optGroupLinker = function ($groupName) { + return 'civicrm/admin/options/' . $groupName . '?reset=1'; + }; + + $childLinks = [ + 'Contract Types' => $optGroupLinker('hrjc_contract_type'), + 'Normal Places of Work' => $optGroupLinker('hrjc_location'), + 'Contract End Reasons' => $optGroupLinker('hrjc_contract_end_reason'), + 'Contract Revision Reasons' => $optGroupLinker('hrjc_revision_change_reason'), + 'Standard Full Time Hours' => 'civicrm/hours_location', + 'Pay Scales' => 'civicrm/pay_scale', + 'Benefits' => $optGroupLinker('hrjc_benefit_name'), + 'Deductions' => $optGroupLinker('hrjc_deduction_name'), + 'Insurance Plan Types' => $optGroupLinker('hrjc_insurance_plantype'), + ]; + + foreach ($childLinks as $itemName => $link) { + $this->createNavItem($itemName, $permission, $parentId, ['url' => $link]); + } + + return TRUE; + } + + /** + * Creates a navigation menu item using the API + * + * @param string $name + * @param string $permission + * @param int $parentID + * @param array $params + * + * @return array + */ + private function createNavItem($name, $permission, $parentID, $params = []) { + $params = array_merge([ + 'name' => $name, + 'label' => ts($name), + 'permission' => $permission, + 'parent_id' => $parentID, + 'is_active' => 1, + ], $params); + + $existing = civicrm_api3('Navigation', 'get', $params); + + if ($existing['count'] > 0) { + return array_shift($existing['values']); + } + + return civicrm_api3('Navigation', 'create', $params); + } + /** * Removes the "Pension Type" item from the * "Administer -> Customize Data and Screens -> Dropdowns" menu diff --git a/hrjobcontract/info.xml b/hrjobcontract/info.xml index 6fa1283915b..01f9cd65b9f 100644 --- a/hrjobcontract/info.xml +++ b/hrjobcontract/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrmed/info.xml b/hrmed/info.xml index f7aa788f211..a7dc8653263 100644 --- a/hrmed/info.xml +++ b/hrmed/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrprofile/info.xml b/hrprofile/info.xml index 5a69393d18f..08d18387b97 100644 --- a/hrprofile/info.xml +++ b/hrprofile/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrqual/info.xml b/hrqual/info.xml index 90f47a8ec96..119509efb49 100644 --- a/hrqual/info.xml +++ b/hrqual/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrrecruitment/CRM/HRRecruitment/Upgrader.php b/hrrecruitment/CRM/HRRecruitment/Upgrader.php index 41bca437eb0..2b0c053ded6 100644 --- a/hrrecruitment/CRM/HRRecruitment/Upgrader.php +++ b/hrrecruitment/CRM/HRRecruitment/Upgrader.php @@ -49,4 +49,27 @@ public function upgrade_1402() { return TRUE; } + + /** + * Upgrade CustomGroup, setting Application, application_case and Evaluation_fields names to is_reserved Yes + * + * @return bool + */ + public function upgrade_1403() { + $result = civicrm_api3('CustomGroup', 'get', [ + 'sequential' => 1, + 'return' => ['id'], + 'name' => ['IN' => ['Application', 'application_case', 'Evaluation_fields']], + ]); + + foreach ($result['values'] as $value) { + civicrm_api3('CustomGroup', 'create', [ + 'id' => $value['id'], + 'is_reserved' => 1, + ]); + } + + return TRUE; + } + } diff --git a/hrrecruitment/info.xml b/hrrecruitment/info.xml index bd33b0c44d4..b7b17903a2b 100644 --- a/hrrecruitment/info.xml +++ b/hrrecruitment/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrreport/info.xml b/hrreport/info.xml index 5eacd53c769..02260d4c59a 100644 --- a/hrreport/info.xml +++ b/hrreport/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrstaffdir/info.xml b/hrstaffdir/info.xml index a377cca7dae..ba116c7a9c6 100644 --- a/hrstaffdir/info.xml +++ b/hrstaffdir/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrui/CRM/HRUI/Upgrader.php b/hrui/CRM/HRUI/Upgrader.php index 3645442b0e4..883b60a142c 100755 --- a/hrui/CRM/HRUI/Upgrader.php +++ b/hrui/CRM/HRUI/Upgrader.php @@ -39,6 +39,8 @@ class CRM_HRUI_Upgrader extends CRM_HRUI_Upgrader_Base { use CRM_HRUI_Upgrader_Steps_4706; use CRM_HRUI_Upgrader_Steps_4707; use CRM_HRUI_Upgrader_Steps_4708; + use CRM_HRUI_Upgrader_Steps_4709; + use CRM_HRUI_Upgrader_Steps_4710; public function install() { $this->runAllUpgraders(); diff --git a/hrui/CRM/HRUI/Upgrader/Steps/4709.php b/hrui/CRM/HRUI/Upgrader/Steps/4709.php new file mode 100644 index 00000000000..1d5b4645365 --- /dev/null +++ b/hrui/CRM/HRUI/Upgrader/Steps/4709.php @@ -0,0 +1,25 @@ + 1, + 'return' => ['id'], + 'name' => 'Inline_Custom_Data', + ]); + + civicrm_api3('CustomGroup', 'create', [ + 'id' => $result['id'], + 'is_reserved' => 1, + ]); + + return TRUE; + } + +} diff --git a/hrui/CRM/HRUI/Upgrader/Steps/4710.php b/hrui/CRM/HRUI/Upgrader/Steps/4710.php new file mode 100644 index 00000000000..f93b9b94ecf --- /dev/null +++ b/hrui/CRM/HRUI/Upgrader/Steps/4710.php @@ -0,0 +1,23 @@ + ['id'], + 'name' => 'Inline_Custom_Data', + ]); + + civicrm_api3('CustomGroup', 'create', [ + 'id' => $result['id'], + 'title' => 'NI/SSN Number', + ]); + + return TRUE; + } + +} diff --git a/hrui/info.xml b/hrui/info.xml index f50dd7776ea..0478f9603ea 100644 --- a/hrui/info.xml +++ b/hrui/info.xml @@ -8,8 +8,8 @@ CiviCRM LLC info@civicrm.org - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/hrui/templates/CRM/Contact/Page/View/Summary.tpl b/hrui/templates/CRM/Contact/Page/View/Summary.tpl index ce11a92063f..d4c338a9b5b 100644 --- a/hrui/templates/CRM/Contact/Page/View/Summary.tpl +++ b/hrui/templates/CRM/Contact/Page/View/Summary.tpl @@ -47,7 +47,7 @@ {* CRM-12735 - Conditionally include the Actions and Edit buttons if contact is NOT in trash.*} {if !$isDeleted} - {if call_user_func(array('CRM_Core_Permission','check'), 'access CiviCRM')} + {if $canAccessCiviCRM}
  • {if !empty($alternativeActionsTemplate)} {include file="$alternativeActionsTemplate"} diff --git a/hrui/templates/CRM/common/footer.tpl b/hrui/templates/CRM/common/footer.tpl index 8c201074f88..7095af499e3 100644 --- a/hrui/templates/CRM/common/footer.tpl +++ b/hrui/templates/CRM/common/footer.tpl @@ -23,7 +23,8 @@ | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ *} -{if call_user_func(array('CRM_Core_Permission','check'), 'access CiviCRM')} + +{if $canAccessCiviCRM } {include file="CRM/common/accesskeys.tpl"} {if !empty($contactId)} {include file="CRM/common/contactFooter.tpl"} @@ -31,15 +32,14 @@
  • \n \n \n
  • \n\n'),e.put("civihr-ui-select/match.tpl.html",'\n {{$select.contactList ? \'-select-\' : $select.placeholder}}\n \n \n \n\n'),e.put("civihr-ui-select/select-contacts-multiple.tpl.html",'
    \n
    \n
      \n \n
    • \n \n
    • \n
    \n\n \n\n \n
    \n
    \n'),e.put("civihr-ui-select/select-contacts.tpl.html",'
    \n
    \n \n
    \n'),e.put("civihr-ui-select/select-multiple.tpl.html",'
    \n
    \n
      \n \n
    • \n \n
    • \n
    \n \n
    \n
    \n'),e.put("civihr-ui-select/select.tpl.html",'
    \n
    \n \n
    \n'),e.put("components/heatmap.html",'
      \n
    • \n {{day.name.short}}\n
    • \n
    \n'),e.put("contact-actions/contact-actions.html",'
    \n \n \n
    \n'),e.put("contact-actions/modals/form.html",'
    \n \n \n \n
    \n')}])}),define("common/modules/controllers",["common/angular","common/angularBootstrap","common/modules/apis"],function(e){"use strict";return e.module("common.controllers",["ui.bootstrap","common.apis"])}),define("common/modules/directives",["common/angular","common/decorators/ui-select-focus.decorator","common/decorators/uib-datepicker-calendar-icon.decorator","common/decorators/uib-datepicker-mobile-version.decorator","common/decorators/xeditable-disable-calendar-icon.decorator","common/decorators/ui-bootstrap/uib-tabset","common/decorators/ui-bootstrap/uib-modal.decorator","common/angularBootstrap","common/angularXeditable","common/ui-select","common/modules/templates","common/modules/controllers","common/modules/services","common/modules/apis"],function(e,t,n,r,i,o,a){"use strict";return e.module("common.directives",["common.templates","common.controllers","ui.select","ui.bootstrap","xeditable"]).config(["$provide",function(e){e.decorator("uibDatepickerPopupDirective",r),e.decorator("uibDatepickerPopupDirective",n),e.decorator("uibTabsetDirective",o),e.decorator("$uibModal",a),e.decorator("editableBsdateDirective",i),e.decorator("uiSelectDirective",t)}]).run(["$templateCache",function(e){var t="uib/template/tabs/tabset.html",n=jQuery(e.get(t));n.find("ul").addClass("{{tabset.customHeaderClass}}"),e.put(t,n.wrap("
    ").parent().html())}])}),define("common/services/api/contact-actions",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.contactActions",["$q","api",function(e,t){function n(e,n){return t.sendGET(e,"getoptions",{field:n,context:"search"}).then(function(e){return e.values})}function r(e){return t.sendGET("UFField","get",{uf_group_id:e,is_active:!0}).then(function(e){return e.values})}function i(n,r){return e(function(e,i){if(r.contact_type=n,r.email)return t.sendGET("CustomField","get",{return:["id"],custom_group_id:"Emergency_Contacts",name:"email"}).then(function(t){r["custom_"+t.id]=r.email,delete r.email,e()});e()}).then(function(){return t.sendPOST("Contact","create",r).then(function(e){return e.values[0]})})}return t.extend({getOptions:{forContactType:function(){return n.call(this,"Contact","contact_type")},forGroup:function(){return n.call(this,"GroupContact","group_id")},forTag:function(){return n.call(this,"EntityTag","tag_id")},forStateProvince:function(){return n.call(this,"Address","state_province_id")},forCountry:function(){return n.call(this,"Address","country_id")},forGender:function(){return n.call(this,"Contact","gender_id")},forDeceased:function(){return n.call(this,"Contact","is_deceased")}},save:{newIndividual:function(e){return i.call(this,"Individual",e)},newOrganization:function(e){return i.call(this,"Organization",e)},newHousehold:function(e){return i.call(this,"Household",e)}},getFormFields:{forNewIndividual:function(){return r.call(this,"new_individual")},forNewOrganization:function(){return r.call(this,"new_organization")},forNewHousehold:function(){return r.call(this,"new_household")}}})}])}),define("common/controllers/contact-actions/modal-ctrl",[],function(){"use strict";return function(e,t){this.errorMsg="",this.loading=!0,this.formFields=[],this.init=function(e){e().then(function(e){this.loading=!1,this.formFields=e}.bind(this)).catch(function(){this.loading=!1,this.errorMsg="Error while loading form fields"}.bind(this))},this.cancel=function(){t.dismiss("cancel")},this.save=function(n,r){this.loading=!0,n(this.formFields.reduce(function(e,t){return e[t.field_name]=t.value,e},{})).then(function(n){this.loading=!1,e.$broadcast(r,n),t.dismiss("cancel")}.bind(this)).catch(function(){this.loading=!1,this.errorMsg="Error while saving data"}.bind(this))}}}),define("common/controllers/contact-actions/new-individual-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Individual",i.init(r.getFormFields.forNewIndividual),i.submit=function(){i.save(r.save.newIndividual,"newIndividualCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewIndividualModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/new-household-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Household",i.init(r.getFormFields.forNewHousehold),i.submit=function(){i.save(r.save.newHousehold,"newHouseholdCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewHouseholdModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/new-organization-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Organization",i.init(r.getFormFields.forNewOrganization),i.submit=function(){i.save(r.save.newOrganization,"newOrganizationCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewOrganizationModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/contact-actions-ctrl",["common/modules/controllers","common/services/api/contact-actions","common/controllers/contact-actions/new-individual-ctrl","common/controllers/contact-actions/new-household-ctrl","common/controllers/contact-actions/new-organization-ctrl"],function(e){"use strict";e.controller("ContactActionsCtrl",["$scope","$rootElement","$uibModal","api.contactActions",function(e,t,n,r){var i=this;e.$watch(function(){return i.refineSearch.selected},function(t,n){t!==n&&e.$emit("contactRefineSearch",{field:t.field?t.field.label:null,option:t.option?t.option.value:null})},!0),i.refineSearch={selected:{field:null,option:null},availableFields:[{label:"Contact Type",getOptions:r.getOptions.forContactType},{label:"Group",getOptions:r.getOptions.forGroup},{label:"Tag",getOptions:r.getOptions.forTag},{label:"State / Province",getOptions:r.getOptions.forStateProvince},{label:"Country",getOptions:r.getOptions.forCountry},{label:"Gender",getOptions:r.getOptions.forGender},{label:"Deceased",getOptions:r.getOptions.forDeceased}],availableOptions:{refresh:function(){i.refineSearch.selected.field?(this.options=null,i.refineSearch.selected.field.getOptions().then(function(e){this.options=e}.bind(this))):this.options=[]},options:[]}},i.showNewIndividualModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewIndividualModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})},i.showNewHouseholdModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewHouseholdModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})},i.showNewOrganizationModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewOrganizationModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})}}])}),define("common/directives/prevent-animations",["common/modules/directives"],function(e){"use strict";e.directive("preventAnimations",["$animate",function(e){return{restrict:"A",link:function(t,n,r){e.enabled(n,!1)}}}])}),define("common/directives/loading",["common/modules/directives","common/directives/prevent-animations"],function(e){"use strict";e.directive("crmLoading",["$templateCache",function(e){return{scope:{show:"="},restrict:"E",replace:!0,transclude:!0,template:e.get("loading.html")}}])}),define("common/directives/contact-actions/contact-actions",["common/modules/directives","common/controllers/contact-actions/contact-actions-ctrl","common/directives/loading"],function(e){"use strict";e.directive("contactActions",[function(){return{restrict:"E",templateUrl:"contact-actions/contact-actions.html",controller:"ContactActionsCtrl",controllerAs:"$ctrl",link:function(e,t,n){e.$ctrl.refineSearchVisible=t.parent().parent()[0].hasAttribute("refine-search")}}}])}),define("common/directives/help-text.directive",["common/lodash","common/moment","common/modules/directives","common/services/notification.service"],function(e,t,n){function r(e,t){function n(){var n=e.getHelpText();t.info(e.title||r,n)}var r="Help";this.displayHelpText=n}function i(e,t,n){function r(){return t.find(".help-text").html()}e.getHelpText=r}n.directive("helpText",["$templateCache",function(e){return{restrict:"E",scope:{title:"@?"},transclude:!0,controller:r,controllerAs:"helpText",template:e.get("help-text.html"),link:i}}]),r.$inject=["$scope","notificationService"]}),define("common/directives/scroll-shadows.directive",["common/angular","common/modules/directives"],function(e,t){"use strict";function n(t,n,r){function i(){u(),a(),l(),s()}function o(){var e=f.width(),t=p+"__shadows--show-left",n=p+"__shadows--show-right",r=d.scrollLeft(),i=d.width();if(e<=i)return void d.removeClass(t+" "+n);d[r>0?"addClass":"removeClass"](t),d[r
    ').parent(),d=f.wrap('
    ').parent(),d.wrap('
    ')}var f,d,p="chr_scroll-shadows";!function(){c(),i(),o()}()}t.directive("scrollShadows",[function(){return{restrict:"A",controller:n}}]),n.$inject=["$element","$scope","$window"]}),define("common/directives/timepicker-select.directive",["common/moment","common/modules/directives"],function(e,t){"use strict";function n(t){function n(){var n=+t.timepickerSelectInterval||1,i=e.duration(t.timepickerSelectTimeFrom||"00:00"),o=e.duration(t.timepickerSelectTimeTo||"23:59");for(r.options=[];i.asMinutes()<=o.asMinutes();){var a=e.utc(i.asMilliseconds());r.options.push(a.format("HH:mm")),i.add(n,"minutes")}}var r=this;r.placeholder=t.timepickerSelectPlaceholder,r.options=[],t.$watchGroup(["timepickerSelectTimeFrom","timepickerSelectTimeTo","timepickerSelectInterval"],function(){n()})}t.directive("timepickerSelect",["$templateCache",function(e){return{scope:{timepickerSelectPlaceholder:"@",timepickerSelectTimeFrom:"<",timepickerSelectTimeTo:"<",timepickerSelectInterval:"<"},restrict:"A",controllerAs:"selector",controller:["$scope",n],template:e.get("timepicker-select.html")}}]),n.$inject=["$scope"]}),define("common/directives/time-amount-picker.directive",["common/lodash","common/modules/directives"],function(e,t){"use strict";function n(t){function n(){var e=Math.floor(c);for(d.hoursOptions=[];e<=f;)d.hoursOptions.push(e),e++}function r(){var e,t,n,r=0;for(d.minutesOptions=[];r<60;)t=+d.selectedHours===Math.floor(c)&&rf%1*60,e=t||n,!e&&d.minutesOptions.push(r),r+=u;l()}function i(){u=+t.interval||1,c=isNaN(+t.minAmount)?0:+t.minAmount,f=isNaN(+t.maxAmount)?24:+t.maxAmount,n(),r()}function o(){""!==d.selectedHours&&""!==d.selectedMinutes&&(t.value=+d.selectedHours+d.selectedMinutes/60)}function a(){t.$watch("disabled",function(e){d.disabled=e}),t.$watch("value",function(){s()}),t.$watchGroup(["minAmount","maxAmount","interval"],function(){i()})}function s(){void 0!==t.value&&(d.selectedHours=""+Math.floor(t.value),d.selectedMinutes=""+Math.floor(t.value%1*60)),o()}function l(){d.selectedMinutese.last(d.minutesOptions)&&(d.selectedMinutes=""+e.last(d.minutesOptions))}var u,c,f,d=this;d.hoursOptions=[],d.minutesOptions=[],d.selectedHours="",d.selectedMinutes="",d.buildMinutesOptions=r,d.calculateSelectedValue=o,function(){s(),a()}()}t.directive("timeAmountPicker",["$templateCache",function(e){return{scope:{minAmount:".75?Math.floor(.25*Math.ceil(e/.25))+"h":"",n=e%1&&e%1<=.75&&e%1>0?.25*Math.ceil(e%1/.25)*60+"m":"",r+t+(t&&n?" ":"")+n)}};return function(t,n){var r=void 0===t?0:parseFloat(t);if(isNaN(r))throw new Error("Value must be a number or a numeric string: "+t);return e[n](r)}})}),define("common/bundles/filters",["common/filters/time-unit-applier.filter"],function(){}),define("common/decorators/angular-date/datepicker-popup",["common/lodash"],function(e){return["$delegate","HR_settings",function(t,n){"use strict";var r=t[0].link;return t[0].compile=function(){return function(t,i,o,a){o.uibDatepickerPopup=o.uibDatepickerPopup||n.DATE_FORMAT||"yyyy-MM-dd",o.showButtonBar=o.showButtonBar||!1,t.datepickerOptions=e.assign({formatDayHeader:"E",showWeeks:!1,startingDay:1},t.datepickerOptions),r.apply(this,arguments)}},t}]}),define("common/decorators/angular-date/date-filter",[],function(){"use strict";return["$delegate",function(e){var t=e;return function(){if("E"===arguments[1]){var e=Array.prototype.slice.call(arguments);return e[1]="EEE",t.apply(this,e)[0]}return t.apply(this,arguments)}}]}), -function(e){define("common/modules/angular-date",["common/angular","common/decorators/angular-date/datepicker-popup","common/decorators/angular-date/date-filter","common/modules/services","common/angularBootstrap","common/modules/templates"],function(t,n,r){"use strict";function i(t){var n="uib/template/datepicker/"+t+".html",r=o.get(n);r=r.replace(/glyphicon glyphicon-chevron-(left|right)/gm,"fa fa-chevron-$1"),"day"===t&&(r=function(t){return e(t).find('th[ng-if="showWeeks"]').parent().css({"border-top":"1px solid #DDD"}),e(t).prop("outerHTML")}(e.parseHTML(r))),o.put(n,r)}var o;return t.module("common.angularDate",["common.services","ui.bootstrap","common.templates"]).config(["$provide",function(e){e.decorator("uibDatepickerPopupDirective",n),e.decorator("dateFilter",r)}]).run(["$templateCache",function(e){o=e,["day","month","year"].forEach(i)}])})}(CRM.$),define("common/services/angular-date/date-format",["common/angular","common/modules/angular-date","common/services/hr-settings"],function(e,t){"use strict";t.factory("DateFormat",["$q","HR_settings",function(e,t){return{dateFormat:null,getDateFormat:function(){return this.dateFormat?e.when(this.dateFormat):e.when("dd/MM/yyyy").catch(function(){return"yyyy-MM-dd"}).then(function(e){return t.DATE_FORMAT=e,this.dateFormat=e,e}.bind(this))}}}])}),define("common/filters/angular-date/format-date",["common/moment","common/modules/angular-date","common/services/hr-settings"],function(e,t){"use strict";t.filter("formatDate",["HR_settings",function(t){var n=["DD-MM-YYYY","DD-MM-YYYY HH:mm:ss","YYYY-MM-DD","YYYY-MM-DD HH:mm:ss","DD/MM/YYYY","x","YYYY-MM-DD HH:mm:ss"];return function(r,i,o){var a,s=i||t.DATE_FORMAT||"YYYY-MM-DD",l=e(0);return r instanceof Date&&(r=e(r).format("YYYY-MM-DD HH:mm:ss")),a=e(r,n,!0),a.isValid()&&!a.isSame(l)?i===Date?a.toDate():a.format(s.toUpperCase())+("hours"===o?" "+a.format("HH:mm"):""):"Unspecified"}}])}),define("common/directives/angular-date/date-input",["common/modules/angular-date","common/filters/angular-date/format-date"],function(e){"use strict";e.directive("dateInput",["$filter",function(e){return{require:"ngModel",link:function(t,n,r,i){function o(t){var n=e("formatDate")(t);return n="Unspecified"==n?"":n}i.$formatters.push(o),i.$parsers=[]}}}])}),define("common/bundles/angular-date",["common/services/angular-date/date-format","common/filters/angular-date/format-date","common/directives/angular-date/date-input"],function(){}),define("common/modules/routers/compu-ng-route",["common/angular","common/angularRoute"],function(e){"use strict";return e.module("compuNgRoute",["ngRoute"]).config(["$routeProvider",function(t){var n=t.when;t.resolveForAll=function(e){return t.commonResolve=e,t},t.when=function(r,i){return e.extend(i.resolve||{},t.commonResolve||{}),n.call(t,r,i)}}])}),"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function r(e,t){return L(new(L(function(){},{prototype:e})),t)}function i(e){return j(arguments,function(t){t!==e&&j(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var r in e.path){if(e.path[r]!==t.path[r])break;n.push(e.path[r])}return n}function a(e){if(Object.keys)return Object.keys(e);var t=[];return j(e,function(e,n){t.push(n)}),t}function s(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,r=Number(arguments[2])||0;for(0>(r=0>r?Math.ceil(r):Math.floor(r))&&(r+=n);n>r;r++)if(r in e&&e[r]===t)return r;return-1}function l(e,t,n,r){var i,l=o(n,r),u={},c=[];for(var f in l)if(l[f].params&&(i=a(l[f].params),i.length))for(var d in i)s(c,i[d])>=0||(c.push(i[d]),u[i[d]]=e[i[d]]);return L({},u,t)}function u(e,t,n){if(!n){n=[];for(var r in e)n.push(r)}for(var i=0;i "));if(y[n]=r,I(e))g.push(n,[function(){return t.get(e)}],u);else{var i=t.annotate(e);j(i,function(e){e!==n&&l.hasOwnProperty(e)&&p(l[e],e)}),g.push(n,e,i)}v.pop(),y[n]=o}}function h(e){return P(e)&&e.then&&e.$$promises}if(!P(l))throw new Error("'invocables' must be an object");var m=a(l||{}),g=[],v=[],y={};return j(l,p),l=v=y=null,function(r,o,a){function s(){--b||($||i(y,o.$$values),p.$$values=y,p.$$promises=p.$$promises||!0,delete p.$$inheritedValues,u.resolve(y))}function l(e){p.$$failure=e,u.reject(e)}if(h(r)&&a===n&&(a=o,o=r,r=null),r){if(!P(r))throw new Error("'locals' must be an object")}else r=c;if(o){if(!h(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=f;var u=e.defer(),p=u.promise,v=p.$$promises={},y=L({},r),b=1+g.length/3,$=!1;if(N(o.$$failure))return l(o.$$failure),p;o.$$inheritedValues&&i(y,d(o.$$inheritedValues,m)),L(v,o.$$promises),o.$$values?($=i(y,d(o.$$values,m)),p.$$inheritedValues=d(o.$$values,m),s()):(o.$$inheritedValues&&(p.$$inheritedValues=d(o.$$inheritedValues,m)),o.then(s,l));for(var w=0,x=g.length;x>w;w+=3)r.hasOwnProperty(g[w])?s():function(n,i,o){function u(e){f.reject(e),l(e)}function c(){if(!N(p.$$failure))try{f.resolve(t.invoke(i,a,y)),f.promise.then(function(e){y[n]=e,s()},u)}catch(e){u(e)}}var f=e.defer(),d=0;j(o,function(e){v.hasOwnProperty(e)&&!r.hasOwnProperty(e)&&(d++,v[e].then(function(t){y[e]=t,--d||c()},u))}),d||c(),v[n]=f.promise}(g[w],g[w+1],g[w+2]);return p}},this.resolve=function(e,t,n,r){return this.study(e)(t,n,r)}}function g(e,t,n){this.fromConfig=function(e,t,n){return N(e.template)?this.fromString(e.template,t):N(e.templateUrl)?this.fromUrl(e.templateUrl,t):N(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return R(e)?e(t):e},this.fromUrl=function(n,r){return R(n)&&(n=n(r)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,r){return n.invoke(e,null,r||{params:t})}}function v(e,t,i){function o(t,n,r,i){if(g.push(t),h[t])return h[t];if(!/^\w+(-+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(m[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return m[t]=new H.Param(t,n,r,i),m[t]}function a(e,t,n,r){var i=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:i=["(",")"+(r?"?":"")];break;case!0:i=["?(",")?"];break;default:i=["("+n+"|",")?"]}return o+i[0]+t+i[1]}function s(i,o){var a,s,l,u,c;return a=i[2]||i[3],c=t.params[a],l=e.substring(d,i.index),s=o?i[4]:i[4]||("*"==i[1]?".*":null),u=H.type(s||"string")||r(H.type("string"),{pattern:new RegExp(s,t.caseInsensitive?"i":n)}),{id:a,regexp:s,segment:l,type:u,cfg:c}}t=L({params:{}},P(t)?t:{});var l,u=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,c=/([:]?)([\w\[\]-]+)|\{([\w\[\]-]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,f="^",d=0,p=this.segments=[],h=i?i.params:{},m=this.params=i?i.params.$$new():new H.ParamSet,g=[];this.source=e;for(var v,y,b;(l=u.exec(e))&&(v=s(l,!1),!(v.segment.indexOf("?")>=0));)y=o(v.id,v.type,v.cfg,"path"),f+=a(v.segment,y.type.pattern.source,y.squash,y.isOptional),p.push(v.segment),d=u.lastIndex;b=e.substring(d);var $=b.indexOf("?");if($>=0){var w=this.sourceSearch=b.substring($);if(b=b.substring(0,$),this.sourcePath=e.substring(0,d+$),w.length>0)for(d=0;l=c.exec(w);)v=s(l,!0),y=o(v.id,v.type,v.cfg,"search"),d=u.lastIndex}else this.sourcePath=e,this.sourceSearch="";f+=a(b)+(!1===t.strict?"/?":"")+"$",p.push(b),this.regexp=new RegExp(f,t.caseInsensitive?"i":n),this.prefix=p[0],this.$$paramNames=g}function y(e){L(this,e)}function b(){function e(e){return null!=e?e.toString().replace(/\//g,"%2F"):e}function i(e){return null!=e?e.toString().replace(/%2F/g,"/"):e}function o(){return{strict:m,caseInsensitive:d}}function l(e){return R(e)||F(e)&&R(e[e.length-1])}function u(){for(;x.length;){var e=x.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend($[e.name],f.invoke(e.def))}}function c(e){L(this,e||{})}H=this;var f,d=!1,m=!0,g=!1,$={},w=!0,x=[],C={string:{encode:e,decode:i,is:function(e){return null==e||!N(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return N(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};b.$$getDefaultValue=function(e){if(!l(e.value))return e.value;if(!f)throw new Error("Injectable functions cannot be called at configuration time");return f.invoke(e.value)},this.caseInsensitive=function(e){return N(e)&&(d=e),d},this.strictMode=function(e){return N(e)&&(m=e),m},this.defaultSquashPolicy=function(e){if(!N(e))return g;if(!0!==e&&!1!==e&&!I(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return g=e,e},this.compile=function(e,t){return new v(e,L(o(),t))},this.isMatcher=function(e){if(!P(e))return!1;var t=!0;return j(v.prototype,function(n,r){R(n)&&(t=t&&N(e[r])&&R(e[r]))}),t},this.type=function(e,t,n){if(!N(t))return $[e];if($.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return $[e]=new y(L({name:e},t)),n&&(x.push({name:e,def:n}),w||u()),this},j(C,function(e,t){$[t]=new y(L({name:t},e))}),$=r($,{}),this.$get=["$injector",function(e){return f=e,w=!1,u(),j(C,function(e,t){$[t]||($[t]=new y(e))}),this}],this.Param=function(e,t,r,i){function o(){if(!f)throw new Error("Injectable functions cannot be called at configuration time");var e=f.invoke(r.$$fn);if(null!==e&&e!==n&&!d.type.is(e))throw new Error("Default value ("+e+") for parameter '"+d.id+"' is not an instance of Type ("+d.type.name+")");return e}function u(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=h(p(d.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),N(e)?d.type.$normalize(e):o()}function c(){return"{Param:"+e+" "+t+" squash: '"+b+"' optional: "+v+"}"}var d=this;r=function(e){var t=P(e)?a(e):[];return-1===s(t,"value")&&-1===s(t,"type")&&-1===s(t,"squash")&&-1===s(t,"array")&&(e={value:e}),e.$$fn=l(e.value)?e.value:function(){return e.value},e}(r),t=function(t,n,r){if(t.type&&n)throw new Error("Param '"+e+"' has two type configurations.");return n||(t.type?t.type instanceof y?t.type:new y(t.type):"config"===r?$.any:$.string)}(r,t,i);var m=function(){var t={array:"search"===i&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return L(t,n,r).array}();t=m?t.$asArray(m,"search"===i):t,"string"!==t.name||m||"path"!==i||r.value!==n||(r.value="");var v=r.value!==n,b=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!N(n)||null==n)return g;if(!0===n||I(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,v),w=function(e,t,r,i){var o,a,l=[{from:"",to:r||t?n:""},{from:null,to:r||t?n:""}];return o=F(e.replace)?e.replace:[],I(i)&&o.push({from:i,to:n}),a=h(o,function(e){return e.from}),p(l,function(e){return-1===s(a,e.from)}).concat(o)}(r,m,v,b);L(this,{id:e,type:t,location:i,array:m,squash:b,replace:w,isOptional:v,value:u,dynamic:n,config:r,toString:c})},c.prototype={$$new:function(){return r(this,L(new c,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,r=a(c.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),j(t,function(t){j(a(t),function(t){-1===s(e,t)&&-1===s(r,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return j(n.$$keys(),function(r){t[r]=n[r].value(e&&e[r])}),t},$$equals:function(e,t){var n=!0,r=this;return j(r.$$keys(),function(i){var o=e&&e[i],a=t&&t[i];r[i].type.equals(o,a)||(n=!1)}),n},$$validates:function(e){var r,i,o,a,s,l=this.$$keys();for(r=0;ri;i++)if(t(u[i]))return;c&&t(c)}}function p(){return l=l||i.$on("$locationChangeSuccess",d)}var h,m=a.baseHref(),g=r.url();return f||p(),{sync:function(){d()},listen:function(){return p()},update:function(e){return e?void(g=r.url()):void(r.url()!==g&&(r.url(g),r.replace()))},push:function(e,t,i){var o=e.format(t||{});null!==o&&t&&t["#"]&&(o+="#"+t["#"]),r.url(o),h=i&&i.$$avoidResync?r.url():n,i&&i.replace&&r.replace()},href:function(n,i,o){if(!n.validates(i))return null;var a=e.html5Mode();t.isObject(a)&&(a=a.enabled);var l=n.format(i);if(o=o||{},a||null===l||(l="#"+e.hashPrefix()+l),null!==l&&i&&i["#"]&&(l+="#"+i["#"]),l=s(l,a,o.absolute),!o.absolute||!l)return l;var u=!a&&l?"/":"",c=r.port();return c=80===c||443===c?"":":"+c,[r.protocol(),"://",r.host(),c,u,l].join("")}}}var l,u=[],c=null,f=!1;this.rule=function(e){if(!R(e))throw new Error("'rule' must be a function");return u.push(e),this},this.otherwise=function(e){if(I(e)){var t=e;e=function(){return t}}else if(!R(e))throw new Error("'rule' must be a function");return c=e,this},this.when=function(e,t){var n,s=I(t);if(I(e)&&(e=r.compile(e)),!s&&!R(t)&&!F(t))throw new Error("invalid 'handler' in when()");var l={matcher:function(e,t){return s&&(n=r.compile(t),t=["$match",function(e){return n.format(e)}]),L(function(n,r){return a(n,t,e.exec(r.path(),r.search()))},{prefix:I(e.prefix)?e.prefix:""})},regex:function(e,t){if(e.global||e.sticky)throw new Error("when() RegExp must not be global or sticky");return s&&(n=t,t=["$match",function(e){return o(n,e)}]),L(function(n,r){return a(n,t,e.exec(r.path()))},{prefix:i(e)})}},u={matcher:r.isMatcher(e),regex:e instanceof RegExp};for(var c in u)if(u[c])return this.rule(l[c](e,t));throw new Error("invalid 'what' in when()")},this.deferIntercept=function(e){e===n&&(e=!0),f=e},this.$get=s,s.$inject=["$location","$rootScope","$injector","$browser"]}function w(e,i){function o(e){return 0===e.indexOf(".")||0===e.indexOf("^")}function d(e,t){if(!e)return n;var r=I(e),i=r?e:e.name;if(o(i)){if(!t)throw new Error("No reference point given for path '"+i+"'");t=d(t);for(var a=i.split("."),s=0,l=a.length,u=t;l>s;s++)if(""!==a[s]||0!==s){if("^"!==a[s])break;if(!u.parent)throw new Error("Path '"+i+"' not valid for state '"+t.name+"'");u=u.parent}else u=t;a=a.slice(s).join("."),i=u.name+(u.name&&a?".":"")+a}var c=E[i];return!c||!r&&(r||c!==e&&c.self!==e)?n:c}function p(e,t){S[e]||(S[e]=[]),S[e].push(t)}function m(e){for(var t=S[e]||[];t.length;)g(t.shift())}function g(t){t=r(t,{self:t,resolve:t.resolve||{},toString:function(){return this.name}});var n=t.name;if(!I(n)||n.indexOf("@")>=0)throw new Error("State must have a valid name");if(E.hasOwnProperty(n))throw new Error("State '"+n+"'' is already defined");var i=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):I(t.parent)?t.parent:P(t.parent)&&I(t.parent.name)?t.parent.name:"";if(i&&!E[i])return p(i,t.self);for(var o in M)R(M[o])&&(t[o]=M[o](t,M.$delegates[o]));return E[n]=t,!t[_]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){k.$current.navigable==t&&u(e,n)||k.transitionTo(t,e,{inherit:!0,location:!1})}]),m(n),t}function v(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=k.$current.name.split("."),r=0,i=t.length;i>r;r++)"*"===t[r]&&(n[r]="*");return"**"===t[0]&&(n=n.slice(s(n,t[1])),n.unshift("**")),"**"===t[t.length-1]&&(n.splice(s(n,t[t.length-2])+1,Number.MAX_VALUE),n.push("**")),t.length==n.length&&n.join("")===t.join("")}function b(e,t){return I(e)&&!N(t)?M[e]:R(t)&&I(e)?(M[e]&&!M.$delegates[e]&&(M.$delegates[e]=M[e]),M[e]=t,this):this}function $(e,t){return P(e)?t=e:t.name=e,g(t),this}function w(e,i,o,s,f,p,m,g,b){function $(t,n,r,o){var a=e.$broadcast("$stateNotFound",t,n,r);if(a.defaultPrevented)return m.update(),T;if(!a.retry)return null;if(o.$retry)return m.update(),D;var s=k.transition=i.when(a.retry);return s.then(function(){return s!==k.transition?S:(t.options.$retry=!0,k.transitionTo(t.to,t.toParams,t.options))},function(){return T}),m.update(),s}function w(e,n,r,a,l,u){function d(){var n=[];return j(e.views,function(r,i){var a=r.resolve&&r.resolve!==e.resolve?r.resolve:{};a.$template=[function(){return o.load(i,{view:r,locals:l.globals,params:p,notify:u.notify})||""}],n.push(f.resolve(a,l.globals,l.resolve,e).then(function(n){if(R(r.controllerProvider)||F(r.controllerProvider)){var o=t.extend({},a,l.globals);n.$$controller=s.invoke(r.controllerProvider,null,o)}else n.$$controller=r.controller;n.$$state=e,n.$$controllerAs=r.controllerAs,l[i]=n}))}),i.all(n).then(function(){return l.globals})}var p=r?n:c(e.params.$$keys(),n),h={$stateParams:p};l.resolve=f.resolve(e.resolve,h,l.resolve,e);var m=[l.resolve.then(function(e){l.globals=e})];return a&&m.push(a),i.all(m).then(d).then(function(e){return l})}var S=i.reject(new Error("transition superseded")),M=i.reject(new Error("transition prevented")),T=i.reject(new Error("transition aborted")),D=i.reject(new Error("transition failed"));return C.locals={resolve:null,globals:{$stateParams:{}}},k={params:{},current:C.self,$current:C,transition:null},k.reload=function(e){return k.transitionTo(k.current,p,{reload:e||!0,inherit:!1,notify:!0})},k.go=function(e,t,n){return k.transitionTo(e,t,L({inherit:!0,relative:k.$current},n))},k.transitionTo=function(t,n,o){n=n||{},o=L({location:!0,inherit:!1,relative:null,notify:!0,reload:!1,$retry:!1},o||{});var a,u=k.$current,f=k.params,h=u.path,g=d(t,o.relative),v=n["#"];if(!N(g)){var y={to:t,toParams:n,options:o},b=$(y,u.self,f,o);if(b)return b;if(t=y.to,n=y.toParams,o=y.options,g=d(t,o.relative),!N(g)){if(!o.relative)throw new Error("No such state '"+t+"'");throw new Error("Could not resolve '"+t+"' from state '"+o.relative+"'")}}if(g[_])throw new Error("Cannot transition to abstract state '"+t+"'");if(o.inherit&&(n=l(p,n||{},k.$current,g)),!g.params.$$validates(n))return D;n=g.params.$$values(n),t=g;var E=t.path,T=0,A=E[T],O=C.locals,R=[];if(o.reload){if(I(o.reload)||P(o.reload)){if(P(o.reload)&&!o.reload.name)throw new Error("Invalid reload state object");var F=!0===o.reload?h[0]:d(o.reload);if(o.reload&&!F)throw new Error("No such reload state '"+(I(o.reload)?o.reload:o.reload.name)+"'");for(;A&&A===h[T]&&A!==F;)O=R[T]=A.locals,T++,A=E[T]}}else for(;A&&A===h[T]&&A.ownParams.$$equals(n,f);)O=R[T]=A.locals,T++,A=E[T];if(x(t,n,u,f,O,o))return v&&(n["#"]=v),k.params=n,U(k.params,p),o.location&&t.navigable&&t.navigable.url&&(m.push(t.navigable.url,n,{$$avoidResync:!0,replace:"replace"===o.location}),m.update(!0)),k.transition=null,i.when(k.current);if(n=c(t.params.$$keys(),n||{}),o.notify&&e.$broadcast("$stateChangeStart",t.self,n,u.self,f).defaultPrevented)return e.$broadcast("$stateChangeCancel",t.self,n,u.self,f),m.update(),M;for(var j=i.when(O),H=T;H=T;r--)a=h[r],a.self.onExit&&s.invoke(a.self.onExit,a.self,a.locals.globals),a.locals=null;for(r=T;r=0?i:i+"@"+(o?o.state.name:"")}function _(e,t){var n,r=e.match(/^\s*({[^}]*})\s*$/);if(r&&(e=t+"("+r[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function M(e){var t=e.parent().inheritedData("$uiView");return t&&t.state&&t.state.name?t.state:void 0}function T(e,n){var r=["location","inherit","reload","absolute"];return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(i,o,a,s){var l=_(a.uiSref,e.current.name),u=null,c=M(o)||e.$current,f="[object SVGAnimatedString]"===Object.prototype.toString.call(o.prop("href"))?"xlink:href":"href",d=null,p="A"===o.prop("tagName").toUpperCase(),h="FORM"===o[0].nodeName,m=h?"action":f,g=!0,v={relative:c,inherit:!0},y=i.$eval(a.uiSrefOpts)||{};t.forEach(r,function(e){e in y&&(v[e]=y[e])});var b=function(n){if(n&&(u=t.copy(n)),g){d=e.href(l.state,u,v);var r=s[1]||s[0];return r&&r.$$addStateInfo(l.state,u),null===d?(g=!1,!1):void a.$set(m,d)}};l.paramExpr&&(i.$watch(l.paramExpr,function(e,t){e!==u&&b(e)},!0),u=t.copy(i.$eval(l.paramExpr))),b(),h||o.bind("click",function(t){if(!((t.which||t.button)>1||t.ctrlKey||t.metaKey||t.shiftKey||o.attr("target"))){var r=n(function(){e.go(l.state,u,v)});t.preventDefault();var i=p&&!d?1:0;t.preventDefault=function(){i--<=0&&n.cancel(r)}}})}}}function D(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs",function(t,r,i){function o(){a()?r.addClass(l):r.removeClass(l)}function a(){for(var e=0;er;r++){o=a[r];var c=this.params[o],f=n[r+1];for(i=0;ir;r++)o=a[r],u[o]=this.params[o].value(t[o]);return u},v.prototype.parameters=function(e){return N(e)?this.params[e]||null:this.$$paramNames},v.prototype.validates=function(e){return this.params.$$validates(e)},v.prototype.format=function(e){function t(e){return encodeURIComponent(e).replace(/-/g,function(e){return"%5C%"+e.charCodeAt(0).toString(16).toUpperCase()})}e=e||{};var n=this.segments,r=this.parameters(),i=this.params;if(!this.validates(e))return null;var o,a=!1,s=n.length-1,l=r.length,u=n[0];for(o=0;l>o;o++){var c=s>o,f=r[o],d=i[f],p=d.value(e[f]),m=d.isOptional&&d.type.equals(d.value(),p),g=!!m&&d.squash,v=d.type.encode(p);if(c){var y=n[o+1];if(!1===g)null!=v&&(u+=F(v)?h(v,t).join("-"):encodeURIComponent(v)),u+=y;else if(!0===g){var b=u.match(/\/$/)?/\/?(.*)/:/(.*)/;u+=y.match(b)[1]}else I(g)&&(u+=g+y)}else{if(null==v||m&&!1!==g)continue;F(v)||(v=[v]),v=h(v,encodeURIComponent).join("&"+f+"="),u+=(a?"&":"?")+f+"="+v,a=!0}}return u},y.prototype.is=function(e,t){return!0},y.prototype.encode=function(e,t){return e},y.prototype.decode=function(e,t){return e},y.prototype.equals=function(e,t){return e==t},y.prototype.$subPattern=function(){var e=this.pattern.toString();return e.substr(1,e.length-2)},y.prototype.pattern=/.*/,y.prototype.toString=function(){return"{Type:"+this.name+"}"},y.prototype.$normalize=function(e){return this.is(e)?e:this.decode(e)},y.prototype.$asArray=function(e,t){function r(e,t){function r(e,t){return function(){return e[t].apply(e,arguments)}}function i(e){return F(e)?e:N(e)?[e]:[]}function o(e){switch(e.length){case 0:return n;case 1:return"auto"===t?e[0]:e;default:return e}}function a(e){return!e}function s(e,t){return function(n){n=i(n);var r=h(n,e);return!0===t?0===p(r,a).length:o(r)}}this.encode=s(r(e,"encode")),this.decode=s(r(e,"decode")),this.is=s(r(e,"is"),!0),this.equals=function(e){return function(t,n){var r=i(t),o=i(n);if(r.length!==o.length)return!1;for(var a=0;a=":n(e.from)}:{"<=":n(e.to)}}function o(e){return e.in?{IN:e.in}:{"NOT IN":e.nin}}return{extend:function(t){return e.assign(Object.create(this),t)},compactFilters:function(t){return t?e.pick(t,function(e){return 0===e||!1===e||!!e}):null},processFilters:function(t){return t?(t=this.compactFilters(t),e.transform(t,function(e,t,n){t.from||t.to?e[n]=i(t):t.in||t.nin?e[n]=o(t):e[n]=t},{})):null}}})}),define("common/models/contact-job-role.model",["common/modules/models","common/models/model","common/instances/contact-job-role-instance.instance","common/services/api/contact-job-role-api.api"],function(e){"use strict";e.factory("ContactJobRole",["$log","Model","ContactJobRoleAPI","ContactJobRoleInstance",function(e,t,n,r){return e.debug("ContactJobRole"),t.extend({all:function(e){return n.all(e).then(function(e){return e.list.map(function(e){return r.init(e,!0)})})}})}])}),define("common/models/instances/group-instance",["common/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("GroupInstance",["ModelInstance",function(e){var t=["id","name","title","description"];return e.extend({fromAPIFilter:function(e,n,r){_.includes(t,r)&&(e[r]=this[r])}})}])}),define("common/mocks/module",["common/angular"],function(e){"use strict";return e.module("common.mocks",[])}),define("common/mocks/services/api/group-mock",["common/lodash","common/mocks/module"],function(e,t){"use strict";t.factory("api.group.mock",["$q",function(t){function n(e){var n=t.defer();return n.resolve(e),n.promise}return{all:function(e,t,r){var i,o,a;return i=r||this.mockedGroups().list,e&&(i=i.filter(function(t){return Object.keys(e).every(function(n){return t[n]===e[n]})})),t&&(o=(t.page-1)*t.size,a=o+t.size,i=i.slice(o,a)),n({list:i,total:i.length,allIds:i.map(function(e){return e.id}).join(",")})},find:function(e,t){return n(t||this.mockedGroups().list.filter(function(t){return t.id===e})[0])},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedGroups:function(){return{total:5,list:[{id:"1",name:"Administrators",title:"Administrators",description:"Contacts in this group are assigned Administrator role permissions.",is_active:"1",visibility:"User and User Admin Only",group_type:["1"],is_hidden:"0",is_reserved:"0"},{id:"2",name:"Newsletter Subscribers",title:"Newsletter Subscribers",is_active:'"1',visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"3",name:"Summer Program Volunteers",title:"Summer Program Volunteers",is_active:"1",visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"4",name:"Advisory Board",title:"Advisory Board",is_active:"1",visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"5",name:"Case_Resources",title:"Case Resources",description:"Contacts in this group are listed with their phone number and email when viewing case. You also can send copies of case activities to these contacts.",is_active:"1",visibility:"User and User Admin Only",where_clause:"...",select_tables:"...",where_tables:"...",group_type:"2",is_hidden:"0",is_reserved:"0"}]}}}}])}),define("common/mocks/data/contact.data",[],function(){return{all:{is_error:0,version:3,count:26,values:[{id:"1",contact_id:"1",display_name:"Dr. Kiara Jensen-Parker",email:"kh.jensen-parker@testing.info",contact_type:"Individual"},{id:"2",contact_id:"2",display_name:"jacobc82@lol.co.pl",email:"cruz.v.jacob@spamalot.com",contact_type:"Individual"},{id:"3",contact_id:"3",display_name:"Mei Müller-Nielsen",email:"mz.mller-nielsen75@infomail.co.pl",contact_type:"Individual"},{id:"4",contact_id:"4",display_name:"Ms. Brigette Deforest",email:"deforest.p.brigette9@fakemail.info",contact_type:"Individual"},{id:"5",contact_id:"5",display_name:"robertsc@testing.net",email:"clintr56@mymail.org",contact_type:"Individual"},{id:"6",contact_id:"6",display_name:"Dr. Allen Samuels Sr.",email:"samuelsa@mymail.org",contact_type:"Individual"},{id:"7",contact_id:"7",display_name:"Mei Wilson",email:"wilson.u.mei59@sample.org",contact_type:"Individual"},{id:"8",contact_id:"8",display_name:"Dr. Betty Díaz",email:"dazb@sample.co.nz",contact_type:"Individual"},{id:"9",contact_id:"9",display_name:"Bob Jones-Dimitrov",email:"bobj@testmail.biz",contact_type:"Individual"},{id:"10",contact_id:"10",display_name:"Truman Samuels III",email:"trumans@spamalot.org",contact_type:"Individual"},{id:"11",contact_id:"11",display_name:"Iris Wagner",email:"iwagner75@notmail.info",contact_type:"Individual"},{id:"12",contact_id:"12",display_name:"Mr. Rosario McReynolds",email:"rosariomcreynolds@testmail.org",contact_type:"Individual"},{id:"13",contact_id:"13",display_name:"Shad Jones-Dimitrov III",email:"shadj@lol.net",contact_type:"Individual"},{id:"14",contact_id:"14",display_name:"Toby Cruz Sr.",email:"",contact_type:"Individual"},{id:"15",contact_id:"15",display_name:"lareedaz61@testing.com",email:"lareedaz61@testing.com",contact_type:"Individual"},{id:"16",contact_id:"16",display_name:"Dr. Jay Deforest",email:"jayd@fishmail.org",contact_type:"Individual"},{id:"17",contact_id:"17",display_name:"Mr. Norris Cruz",email:"norriscruz@spamalot.info",contact_type:"Individual"},{id:"18",contact_id:"18",display_name:"herminiac@fishmail.com",email:"herminiac@fishmail.com",contact_type:"Individual"},{id:"19",contact_id:"19",display_name:"Ashley Terrell",email:"terrell.ashley@testmail.info",contact_type:"Individual"},{id:"20",contact_id:"20",display_name:"Kandace Parker-Díaz",email:"parker-daz.kandace67@fishmail.co.uk",contact_type:"Individual"},{id:"21",contact_id:"21",display_name:"Nicole Samuels",email:"ng.samuels@testmail.net",contact_type:"Individual"},{id:"22",contact_id:"22",display_name:"Dr. Kandace Wattson",email:"kandacewattson@testing.info",contact_type:"Individual"},{id:"23",contact_id:"23",display_name:"Brittney Cruz",email:"cruz.brittney@spamalot.co.nz",contact_type:"Individual"},{id:"24",contact_id:"24",display_name:"Shauna Olsen",email:"",contact_type:"Individual"},{id:"202",contact_id:"202",display_name:"civihr_staff@compucorp.co.uk",email:"civihr_staff@compucorp.co.uk",contact_type:"Individual"},{id:"203",contact_id:"203",display_name:"civihr_manager@compucorp.co.uk",email:"civihr_manager@compucorp.co.uk",contact_type:"Individual"}]}}}),define("common/mocks/services/api/contact-mock",["common/lodash","common/mocks/module","common/mocks/data/contact.data"],function(e,t,n){"use strict";t.factory("api.contact.mock",["$q",function(t){function r(e){var n=t.defer();return n.resolve(e),n.promise}return{all:function(t,i,o,a,s){var l,u,c;return l=s||n.all.values,t&&(l=l.filter(function(n){return Object.keys(t).every(function(r){return null===t[r]||("display_name"===r?new RegExp(t[r],"i").test(n[r]):t[r].IN?e.includes(t[r].IN,n[r]):n[r]===t[r])})})),i&&(u=(i.page-1)*i.size,c=u+i.size,l=l.slice(u,c)),r({list:l,total:l.length,allIds:l.map(function(e){return e.id}).join(",")})},find:function(e,t){return r(t||n.all.values.filter(function(t){return t.id===e})[0])},leaveManagees:function(){return r(this.mockedContacts().list)},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedContacts:function(){var e=n.all.values;return{total:e.length,list:e.map(function(e){return e})}}}}])}),define("common/mocks/services/api/group-contact-mock",["common/lodash","common/mocks/module","common/mocks/services/api/contact-mock","common/mocks/services/api/group-mock"],function(e,t){"use strict";t.factory("api.group-contact.mock",["$q","api.contact.mock","api.group.mock",function(t,n,r){function i(t){return e.sample(t)}function o(e){var n=t.defer();return n.resolve(e),n.promise}var a=n.mockedContacts().list,s=r.mockedGroups().list;return{all:function(e,t,n){var r,i,a;return r=n||this.mockedGroupsContacts.list,e&&(r=r.filter(function(t){return Object.keys(e).every(function(n){return t[n]===e[n]})})),t&&(i=(t.page-1)*t.size,a=i+t.size,r=r.slice(i,a)),o({list:r,total:r.length,allIds:r.map(function(e){return e.id}).join(",")})},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedGroupsContacts:{total:a.length,list:function(){var e=1;return a.map(function(t){return{id:""+e++,group_id:i(s).id,contact_id:t.id,status:"Added"}})}()}}}])}),define("common/models/group",["common/modules/models","common/models/model","common/models/instances/group-instance","common/mocks/services/api/group-mock","common/mocks/services/api/group-contact-mock"],function(e){"use strict";e.factory("Group",["Model","api.group.mock","api.group-contact.mock","GroupInstance",function(e,t,n,r){return e.extend({all:function(e,n){return t.all(this.processFilters(e),n).then(function(e){return e.list=e.list.map(function(e){return r.init(e,!0)}),e})},find:function(e){return t.find(e).then(function(e){return r.init(e,!0)})},contactIdsOf:function(e){return n.all({group_id:e}).then(function(e){return e.list.map(function(e){return e.contact_id})})}})}])}),define("common/models/instances/job-role-instance",["common/lodash","common/moment","common/modules/models-instances","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("JobRoleInstance",["ModelInstance","HR_settings",function(n,r){return n.extend({fromAPIFilter:function(n,i,o){var a=r.DATE_FORMAT.toUpperCase();e.endsWith(o,"_date")?n[o]=t(this[o],"YYYY-MM-DD HH:mm:ss").format(a):"api.HRJobContract.getsingle"===o?(n.contact_id=this[o].contact_id,n.job_contract_id=this[o].id):n[o]=this[o]},toAPIFilter:function(n,i,o){var a=["contact_id","job_contract_id"],s=r.DATE_FORMAT.toUpperCase();if(e.endsWith(o,"_date"))n[o]=t(this[o],s).format("YYYY-MM-DD HH:mm:ss");else{if(e.includes(a,o))return;n[o]=this[o]}}})}])}),define("common/services/api/job-role",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.job-role",["$log","api",function(e,t){return e.debug("api.jobRole"),t.extend({all:function(t,n,r,i){return e.debug("api.jobRole.api"),this.getAll("HrJobRoles",t,n,r,i)},find:function(t){return e.debug("api.jobRole.find"),this.sendGET("HRJobRole","get",{id:""+t},!1).then(function(e){return e.values[0]})}})}])}),define("common/models/job-role",["common/modules/models","common/models/model","common/models/instances/job-role-instance","common/services/api/job-role"],function(e){"use strict";e.factory("JobRole",["Model","api.job-role","JobRoleInstance",function(e,t,n){return e.extend({all:function(e,r){return t.all(this.processFilters(e),r).then(function(e){return e.list=e.list.map(function(e){return n.init(e,!0)}),e})},find:function(e){return t.find(e).then(function(e){return n.init(e,!0)})}})}])}),define("common/services/api/contact",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.contact",["$log","api",function(e,t){return e.debug("api.contact"),t.extend({all:function(t,n,r,i){return e.debug("api.contact.api"),this.getAll("Contact",t,n,r,i)},find:function(t){return e.debug("api.contact.find"),this.sendGET("Contact","get",{id:""+t},!1).then(function(e){return e.values[0]})},leaveManagees:function(t,n){return e.debug("api.contact.leaveManagees"),n=_.assign({},n,{managed_by:t}),this.sendGET("Contact","getleavemanagees",n).then(function(e){return e.values})}})}])}),define("common/models/instances/contact-instance",["common/modules/models-instances","common/models/instances/instance","common/services/api/contact"],function(e){"use strict";e.factory("ContactInstance",["ModelInstance","api.contact",function(e,t){return e.extend({leaveManagees:function(e){return t.leaveManagees(this.id,e)}})}])}),define("common/models/contact",["common/lodash","common/modules/models","common/models/model","common/models/contact-job-role.model","common/models/group","common/models/job-role","common/models/instances/contact-instance","common/services/api/contact"],function(e,t){"use strict";t.factory("Contact",["$q","Model","api.contact","Group","JobRole","ContactJobRole","ContactInstance",function(t,n,r,i,o,a,s){function l(t,n){return!e.isEmpty(e.intersection(e.keys(t),n))}function u(e){return a.all(e).then(function(e){return e.map(function(e){return e.contact_id})})}function c(t,n){return e(t).omit(d).omit(p).assign({id:{in:e.intersection.apply(null,n)}}).value()}function f(n){var r=t.defer(),o=[];return n=this.compactFilters(n),l(n,p)&&o.push(u(e.pick(n,p))),l(n,d)&&o.push(i.contactIdsOf(n.group_id)),e.isEmpty(o)?r.resolve(this.processFilters(n)):t.all(o).then(function(e){n=c(n,e),r.resolve(this.processFilters(n))}.bind(this)),r.promise}var d=["group_id"],p=["region","department","level_type","location"];return n.extend({all:function(e,t,n,i){return f.call(this,e).then(function(e){return e&&e.id&&!e.id.IN.length?{list:[]}:r.all(e,t,n,i)}).then(function(e){return e.list=e.list.map(function(e){return s.init(e,!0)}),e})},find:function(e){return r.find(e).then(function(e){return s.init(e,!0)})},leaveManagees:function(e,t){return f.call(this,t).then(function(t){return t&&t.id&&!t.id.IN.length?[]:r.leaveManagees(e,t)})}})}])}),define("common/models/instances/contract-instance",["common/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("ContractInstance",["ModelInstance",function(e){return e.extend({})}])}),define("common/services/api/contract",["common/lodash","common/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("api.contract",["$log","api",function(t,n){function r(t){var n=e.clone(t);return n.info=n["api.HRJobContract.getfulldetails"],delete n["api.HRJobContract.getfulldetails"],n}return t.debug("api.contract"),n.extend({all:function(e){return t.debug("ContractAPI.all"),e=e||{},e["api.HRJobContract.getfulldetails"]={jobcontract_id:"$value.id"},e.deleted=0,this.sendGET("HRJobContract","get",e,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r)})}})}])}),define("common/models/contract",["common/modules/models","common/models/model","common/models/instances/contract-instance","common/services/api/contract"],function(e){"use strict";e.factory("Contract",["$log","Model","api.contract","ContractInstance",function(e,t,n,r){return e.debug("Contract"),t.extend({all:function(e){return n.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})}})}])}),define("common/models/option-group",["common/modules/models","common/models/model","common/services/api/option-group"],function(e){"use strict";e.factory("OptionGroup",["Model","api.optionGroup",function(e,t){return e.extend({valuesOf:function(e){return t.valuesOf(e)}})}])}),function(e,t){define("common/models/session.model",["common/modules/models","common/models/model"],function(n){"use strict";n.factory("Session",["$log","$q","Model",function(n,r,i){return n.debug("Session"),i.extend({get:function(){var n={contactId:e.vars.session?e.vars.session.contact_id:t.settings.currentCiviCRMUserId};if(!n.contactId)throw new Error("Session Error: *Logged In Contact Id* is not defined");return r.resolve(n)}})}])})}(CRM,window.Drupal),define("common/bundles/models",["common/instances/contact-job-role-instance.instance","common/models/model","common/models/contact","common/models/contact-job-role.model","common/models/contract","common/models/group","common/models/job-role","common/models/option-group","common/models/session.model","common/models/instances/instance","common/models/instances/contact-instance","common/models/instances/contract-instance","common/models/instances/group-instance","common/models/instances/job-role-instance"],function(){}),define("common/services/dialog/dialog",["common/lodash","common/modules/services"],function(e,t){"use strict";function n(t,n,r){function i(i){var o;if(!e.isObject(i))throw new Error("Dialog Service: Options passed should be an object");return o=n.children(),t.open({appendTo:o.length?o.eq(0):n,size:"sm",controller:"DialogController",template:r.get("dialog.html"),resolve:{options:function(){return i}}}).result}return{open:i}}t.factory("dialog",n),n.$inject=["$uibModal","$rootElement","$templateCache"]}),define("common/controllers/dialog/dialog-ctrl",["common/lodash","common/modules/controllers"],function(e,t){"use strict";function n(t,n,r,i){function o(t){e.assign(n,e.defaultsDeep(t,{title:"CiviHR",msg:"",copyConfirm:"",copyCancel:"",classConfirm:"btn-primary",loading:!1}))}function a(){r.close(!1)}function s(){n.loading=!0,r.closed.then(n.onCloseAfterConfirm),t.resolve().then(n.onConfirm).then(function(){r.close(!0)})}n.cancel=a,n.confirm=s,function(){o(i),i.optionsPromise&&i.optionsPromise().then(function(e){o(e)})}()}t.controller("DialogController",n),n.$inject=["$q","$scope","$uibModalInstance","options"]}),define("common/modules/dialog",["common/angular","common/services/dialog/dialog","common/controllers/dialog/dialog-ctrl","common/angularBootstrap","common/directives/loading","common/modules/templates"],function(e){"use strict";return e.module("common.dialog",["ui.bootstrap","common.directives","common.templates"])}),define("common/decorators/xeditable-civi/editable-directive-factory",[],function(){"use strict";return["$delegate",function(e){return function(t){var n=e(t);return n.compile=function(e){var t,r=e[0].attributes.getNamedItem("ng-href");return e.append(''),r&&(t=angular.element(""),t.text("Follow link"),t.attr(r.nodeName,r.value),t.attr("ng-click","$event.stopPropagation();"),t.addClass("editable-link"),e.append(t),e.addClass("editable-with-link")),{post:n.link}},n}}]}),define("common/directives/xeditable-civi/editable-ta",[],function(){"use strict";return["editableDirectiveFactory","$timeout",function(e,t){var n,r;return r=e({directiveName:"editableTa",inputTpl:"",render:function(){this.parent.render.call(this),this.inputEl.parent().parent().removeClass("form-inline"),this.inputEl.addClass("editable-ta"),this.inputEl.attr("ng-model","ta.$data"),this.inputEl.attr("ta-toolbar",this.attrs.eTaToolbar||'[["bold","italics","underline","strikeThrough","ul","ol","undo","redo","clear"]]'),t(function(){this.inputEl.find("textarea").hide()}.bind(this),0)},save:function(){this.scope.$data=this.scope.ta.$data,this.parent.save.call(this)},setLocalValue:function(){this.parent.setLocalValue.call(this),this.scope.ta.$data=this.scope.$data}}),n=r.link,r.link=function(e,t,r,i){return e.ta={},n(e,t,r,i)},r}]}),define("common/modules/xeditable-civi",["common/angular","common/decorators/xeditable-civi/editable-directive-factory","common/directives/xeditable-civi/editable-ta","common/angularXeditable","common/text-angular"],function(e,t,n){"use strict";return e.module("xeditable-civi",["xeditable","textAngular"]).directive("editableTa",n)}); +this.date(a.getUTCDate()),this}function Ut(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)}function Ht(e){return me(e,this._week.dow,this._week.doy).week}function qt(){return this._week.dow}function Vt(){return this._week.doy}function zt(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")}function Bt(e){var t=me(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")}function Yt(e,t){return"string"!=typeof e?e:isNaN(e)?(e=t.weekdaysParse(e),"number"==typeof e?e:null):parseInt(e,10)}function Wt(e,n){return t(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(n)?"format":"standalone"][e.day()]}function Gt(e){return this._weekdaysShort[e.day()]}function Kt(e){return this._weekdaysMin[e.day()]}function Zt(e,t,n){var r,i,o;for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;7>r;r++){if(i=Te([2e3,1]).day(r),n&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(i,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(i,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(i,"").replace(".",".?")+"$","i")),this._weekdaysParse[r]||(o="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[r]=new RegExp(o.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[r].test(e))return r;if(n&&"ddd"===t&&this._shortWeekdaysParse[r].test(e))return r;if(n&&"dd"===t&&this._minWeekdaysParse[r].test(e))return r;if(!n&&this._weekdaysParse[r].test(e))return r}}function Jt(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=Yt(e,this.localeData()),this.add(e-t,"d")):t}function Qt(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")}function Xt(e){return this.isValid()?null==e?this.day()||7:this.day(this.day()%7?e:e-7):null!=e?this:NaN}function en(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")}function tn(){return this.hours()%12||12}function nn(e,t){R(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function rn(e,t){return t._meridiemParse}function on(e){return"p"===(e+"").toLowerCase().charAt(0)}function an(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"}function sn(e,t){t[_r]=g(1e3*("0."+e))}function ln(){return this._isUTC?"UTC":""}function un(){return this._isUTC?"Coordinated Universal Time":""}function cn(e){return Te(1e3*e)}function fn(){return Te.apply(null,arguments).parseZone()}function dn(e,t,n){var r=this._calendar[e];return M(r)?r.call(t,n):r}function pn(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])}function hn(){return this._invalidDate}function mn(e){return this._ordinal.replace("%d",e)}function gn(e){return e}function vn(e,t,n,r){var i=this._relativeTime[n];return M(i)?i(e,t,n,r):i.replace(/%d/i,e)}function yn(e,t){var n=this._relativeTime[e>0?"future":"past"];return M(n)?n(t):n.replace(/%s/i,t)}function bn(e){var t,n;for(n in e)t=e[n],M(t)?this[n]=t:this["_"+n]=t;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function $n(e,t,n,r){var i=k(),o=a().set(r,t);return i[n](o,e)}function wn(e,t,n,r,i){if("number"==typeof e&&(t=e,e=void 0),e=e||"",null!=t)return $n(e,t,n,i);var o,a=[];for(o=0;r>o;o++)a[o]=$n(e,o,n,i);return a}function xn(e,t){return wn(e,t,"months",12,"month")}function Cn(e,t){return wn(e,t,"monthsShort",12,"month")}function kn(e,t){return wn(e,t,"weekdays",7,"day")}function En(e,t){return wn(e,t,"weekdaysShort",7,"day")}function Sn(e,t){return wn(e,t,"weekdaysMin",7,"day")}function _n(){var e=this._data;return this._milliseconds=gi(this._milliseconds),this._days=gi(this._days),this._months=gi(this._months),e.milliseconds=gi(e.milliseconds),e.seconds=gi(e.seconds),e.minutes=gi(e.minutes),e.hours=gi(e.hours),e.months=gi(e.months),e.years=gi(e.years),this}function Mn(e,t,n,r){var i=Ze(t,n);return e._milliseconds+=r*i._milliseconds,e._days+=r*i._days,e._months+=r*i._months,e._bubble()}function Tn(e,t){return Mn(this,e,t,1)}function Dn(e,t){return Mn(this,e,t,-1)}function An(e){return 0>e?Math.floor(e):Math.ceil(e)}function On(){var e,t,n,r,i,o=this._milliseconds,a=this._days,s=this._months,l=this._data;return o>=0&&a>=0&&s>=0||0>=o&&0>=a&&0>=s||(o+=864e5*An(Rn(s)+a),a=0,s=0),l.milliseconds=o%1e3,e=m(o/1e3),l.seconds=e%60,t=m(e/60),l.minutes=t%60,n=m(t/60),l.hours=n%24,a+=m(n/24),i=m(Nn(a)),s+=i,a-=An(Rn(i)),r=m(s/12),s%=12,l.days=a,l.months=s,l.years=r,this}function Nn(e){return 4800*e/146097}function Rn(e){return 146097*e/4800}function In(e){var t,n,r=this._milliseconds;if("month"===(e=S(e))||"year"===e)return t=this._days+r/864e5,n=this._months+Nn(t),"month"===e?n:n/12;switch(t=this._days+Math.round(Rn(this._months)),e){case"week":return t/7+r/6048e5;case"day":return t+r/864e5;case"hour":return 24*t+r/36e5;case"minute":return 1440*t+r/6e4;case"second":return 86400*t+r/1e3;case"millisecond":return Math.floor(864e5*t)+r;default:throw new Error("Unknown unit "+e)}}function Pn(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*g(this._months/12)}function Fn(e){return function(){return this.as(e)}}function jn(e){return e=S(e),this[e+"s"]()}function Ln(e){return function(){return this._data[e]}}function Un(){return m(this.days()/7)}function Hn(e,t,n,r,i){return i.relativeTime(t||1,!!n,e,r)}function qn(e,t,n){var r=Ze(e).abs(),i=Oi(r.as("s")),o=Oi(r.as("m")),a=Oi(r.as("h")),s=Oi(r.as("d")),l=Oi(r.as("M")),u=Oi(r.as("y")),c=i=o&&["m"]||o=a&&["h"]||a=s&&["d"]||s=l&&["M"]||l=u&&["y"]||["yy",u];return c[2]=t,c[3]=+e>0,c[4]=n,Hn.apply(null,c)}function Vn(e,t){return void 0!==Ni[e]&&(void 0===t?Ni[e]:(Ni[e]=t,!0))}function zn(e){var t=this.localeData(),n=qn(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)}function Bn(){var e,t,n,r=Ri(this._milliseconds)/1e3,i=Ri(this._days),o=Ri(this._months);e=m(r/60),t=m(e/60),r%=60,e%=60,n=m(o/12),o%=12;var a=n,s=o,l=i,u=t,c=e,f=r,d=this.asSeconds();return d?(0>d?"-":"")+"P"+(a?a+"Y":"")+(s?s+"M":"")+(l?l+"D":"")+(u||c||f?"T":"")+(u?u+"H":"")+(c?c+"M":"")+(f?f+"S":""):"P0D"}var Yn,Wn,Gn=e.momentProperties=[],Kn=!1,Zn={},Jn={},Qn=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Xn=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,er={},tr={},nr=/\d/,rr=/\d\d/,ir=/\d{3}/,or=/\d{4}/,ar=/[+-]?\d{6}/,sr=/\d\d?/,lr=/\d\d\d\d?/,ur=/\d\d\d\d\d\d?/,cr=/\d{1,3}/,fr=/\d{1,4}/,dr=/[+-]?\d{1,6}/,pr=/\d+/,hr=/[+-]?\d+/,mr=/Z|[+-]\d\d:?\d\d/gi,gr=/Z|[+-]\d\d(?::?\d\d)?/gi,vr=/[+-]?\d+(\.\d{1,3})?/,yr=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,br={},$r={},wr=0,xr=1,Cr=2,kr=3,Er=4,Sr=5,_r=6,Mr=7,Tr=8;R("M",["MM",2],"Mo",function(){return this.month()+1}),R("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),R("MMMM",0,0,function(e){return this.localeData().months(this,e)}),E("month","M"),L("M",sr),L("MM",sr,rr),L("MMM",function(e,t){return t.monthsShortRegex(e)}),L("MMMM",function(e,t){return t.monthsRegex(e)}),V(["M","MM"],function(e,t){t[xr]=g(e)-1}),V(["MMM","MMMM"],function(e,t,n,r){var i=n._locale.monthsParse(e,r,n._strict);null!=i?t[xr]=i:l(n).invalidMonth=e});var Dr=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Ar="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Or="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Nr=yr,Rr=yr,Ir={};e.suppressDeprecationWarnings=!1;var Pr=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Fr=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,jr=/Z|[+-]\d\d(?::?\d\d)?/,Lr=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Ur=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Hr=/^\/?Date\((\-?\d+)/i;e.createFromInputFallback=ie("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),R("Y",0,0,function(){var e=this.year();return 9999>=e?""+e:"+"+e}),R(0,["YY",2],0,function(){return this.year()%100}),R(0,["YYYY",4],0,"year"),R(0,["YYYYY",5],0,"year"),R(0,["YYYYYY",6,!0],0,"year"),E("year","y"),L("Y",hr),L("YY",sr,rr),L("YYYY",fr,or),L("YYYYY",dr,ar),L("YYYYYY",dr,ar),V(["YYYYY","YYYYYY"],wr),V("YYYY",function(t,n){n[wr]=2===t.length?e.parseTwoDigitYear(t):g(t)}),V("YY",function(t,n){n[wr]=e.parseTwoDigitYear(t)}),V("Y",function(e,t){t[wr]=parseInt(e,10)}),e.parseTwoDigitYear=function(e){return g(e)+(g(e)>68?1900:2e3)};var qr=T("FullYear",!1);e.ISO_8601=function(){};var Vr=ie("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var e=Te.apply(null,arguments);return this.isValid()&&e.isValid()?this>e?this:e:c()}),zr=ie("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var e=Te.apply(null,arguments);return this.isValid()&&e.isValid()?e>this?this:e:c()}),Br=function(){return Date.now?Date.now():+new Date};Ie("Z",":"),Ie("ZZ",""),L("Z",gr),L("ZZ",gr),V(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Pe(gr,e)});var Yr=/([\+\-]|\d\d)/gi;e.updateOffset=function(){};var Wr=/(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Gr=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;Ze.fn=Ne.prototype;var Kr=et(1,"add"),Zr=et(-1,"subtract");e.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Jr=ie("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});R(0,["gg",2],0,function(){return this.weekYear()%100}),R(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Nt("gggg","weekYear"),Nt("ggggg","weekYear"),Nt("GGGG","isoWeekYear"),Nt("GGGGG","isoWeekYear"),E("weekYear","gg"),E("isoWeekYear","GG"),L("G",hr),L("g",hr),L("GG",sr,rr),L("gg",sr,rr),L("GGGG",fr,or),L("gggg",fr,or),L("GGGGG",dr,ar),L("ggggg",dr,ar),z(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,r){t[r.substr(0,2)]=g(e)}),z(["gg","GG"],function(t,n,r,i){n[i]=e.parseTwoDigitYear(t)}),R("Q",0,"Qo","quarter"),E("quarter","Q"),L("Q",nr),V("Q",function(e,t){t[xr]=3*(g(e)-1)}),R("w",["ww",2],"wo","week"),R("W",["WW",2],"Wo","isoWeek"),E("week","w"),E("isoWeek","W"),L("w",sr),L("ww",sr,rr),L("W",sr),L("WW",sr,rr),z(["w","ww","W","WW"],function(e,t,n,r){t[r.substr(0,1)]=g(e)});var Qr={dow:0,doy:6};R("D",["DD",2],"Do","date"),E("date","D"),L("D",sr),L("DD",sr,rr),L("Do",function(e,t){return e?t._ordinalParse:t._ordinalParseLenient}),V(["D","DD"],Cr),V("Do",function(e,t){t[Cr]=g(e.match(sr)[0],10)});var Xr=T("Date",!0);R("d",0,"do","day"),R("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),R("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),R("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),R("e",0,0,"weekday"),R("E",0,0,"isoWeekday"),E("day","d"),E("weekday","e"),E("isoWeekday","E"),L("d",sr),L("e",sr),L("E",sr),L("dd",yr),L("ddd",yr),L("dddd",yr),z(["dd","ddd","dddd"],function(e,t,n,r){var i=n._locale.weekdaysParse(e,r,n._strict);null!=i?t.d=i:l(n).invalidWeekday=e}),z(["d","e","E"],function(e,t,n,r){t[r]=g(e)});var ei="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ti="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),ni="Su_Mo_Tu_We_Th_Fr_Sa".split("_");R("DDD",["DDDD",3],"DDDo","dayOfYear"),E("dayOfYear","DDD"),L("DDD",cr),L("DDDD",ir),V(["DDD","DDDD"],function(e,t,n){n._dayOfYear=g(e)}),R("H",["HH",2],0,"hour"),R("h",["hh",2],0,tn),R("hmm",0,0,function(){return""+tn.apply(this)+N(this.minutes(),2)}),R("hmmss",0,0,function(){return""+tn.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)}),R("Hmm",0,0,function(){return""+this.hours()+N(this.minutes(),2)}),R("Hmmss",0,0,function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)}),nn("a",!0),nn("A",!1),E("hour","h"),L("a",rn),L("A",rn),L("H",sr),L("h",sr),L("HH",sr,rr),L("hh",sr,rr),L("hmm",lr),L("hmmss",ur),L("Hmm",lr),L("Hmmss",ur),V(["H","HH"],kr),V(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),V(["h","hh"],function(e,t,n){t[kr]=g(e),l(n).bigHour=!0}),V("hmm",function(e,t,n){var r=e.length-2;t[kr]=g(e.substr(0,r)),t[Er]=g(e.substr(r)),l(n).bigHour=!0}),V("hmmss",function(e,t,n){var r=e.length-4,i=e.length-2;t[kr]=g(e.substr(0,r)),t[Er]=g(e.substr(r,2)),t[Sr]=g(e.substr(i)),l(n).bigHour=!0}),V("Hmm",function(e,t,n){var r=e.length-2;t[kr]=g(e.substr(0,r)),t[Er]=g(e.substr(r))}),V("Hmmss",function(e,t,n){var r=e.length-4,i=e.length-2;t[kr]=g(e.substr(0,r)),t[Er]=g(e.substr(r,2)),t[Sr]=g(e.substr(i))});var ri=/[ap]\.?m?\.?/i,ii=T("Hours",!0);R("m",["mm",2],0,"minute"),E("minute","m"),L("m",sr),L("mm",sr,rr),V(["m","mm"],Er);var oi=T("Minutes",!1);R("s",["ss",2],0,"second"),E("second","s"),L("s",sr),L("ss",sr,rr),V(["s","ss"],Sr);var ai=T("Seconds",!1);R("S",0,0,function(){return~~(this.millisecond()/100)}),R(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),R(0,["SSS",3],0,"millisecond"),R(0,["SSSS",4],0,function(){return 10*this.millisecond()}),R(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),R(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),R(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),R(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),R(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),E("millisecond","ms"),L("S",cr,nr),L("SS",cr,rr),L("SSS",cr,ir);var si;for(si="SSSS";si.length<=9;si+="S")L(si,pr);for(si="S";si.length<=9;si+="S")V(si,sn);var li=T("Milliseconds",!1);R("z",0,0,"zoneAbbr"),R("zz",0,0,"zoneName");var ui=p.prototype;ui.add=Kr,ui.calendar=nt,ui.clone=rt,ui.diff=ct,ui.endOf=xt,ui.format=ht,ui.from=mt,ui.fromNow=gt,ui.to=vt,ui.toNow=yt,ui.get=O,ui.invalidAt=At,ui.isAfter=it,ui.isBefore=ot,ui.isBetween=at,ui.isSame=st,ui.isSameOrAfter=lt,ui.isSameOrBefore=ut,ui.isValid=Tt,ui.lang=Jr,ui.locale=bt,ui.localeData=$t,ui.max=zr,ui.min=Vr,ui.parsingFlags=Dt,ui.set=O,ui.startOf=wt,ui.subtract=Zr,ui.toArray=St,ui.toObject=_t,ui.toDate=Et,ui.toISOString=pt,ui.toJSON=Mt,ui.toString=dt,ui.unix=kt,ui.valueOf=Ct,ui.creationData=Ot,ui.year=qr,ui.isLeapYear=de,ui.weekYear=Rt,ui.isoWeekYear=It,ui.quarter=ui.quarters=Ut,ui.month=J,ui.daysInMonth=Q,ui.week=ui.weeks=zt,ui.isoWeek=ui.isoWeeks=Bt,ui.weeksInYear=Ft,ui.isoWeeksInYear=Pt,ui.date=Xr,ui.day=ui.days=Jt,ui.weekday=Qt,ui.isoWeekday=Xt,ui.dayOfYear=en,ui.hour=ui.hours=ii,ui.minute=ui.minutes=oi,ui.second=ui.seconds=ai,ui.millisecond=ui.milliseconds=li,ui.utcOffset=Le,ui.utc=He,ui.local=qe,ui.parseZone=Ve,ui.hasAlignedHourOffset=ze,ui.isDST=Be,ui.isDSTShifted=Ye,ui.isLocal=We,ui.isUtcOffset=Ge,ui.isUtc=Ke,ui.isUTC=Ke,ui.zoneAbbr=ln,ui.zoneName=un,ui.dates=ie("dates accessor is deprecated. Use date instead.",Xr),ui.months=ie("months accessor is deprecated. Use month instead",J),ui.years=ie("years accessor is deprecated. Use year instead",qr),ui.zone=ie("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Ue);var ci=ui,fi={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},di={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},pi=/\d{1,2}/,hi={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},mi=y.prototype;mi._calendar=fi,mi.calendar=dn,mi._longDateFormat=di,mi.longDateFormat=pn,mi._invalidDate="Invalid date",mi.invalidDate=hn,mi._ordinal="%d",mi.ordinal=mn,mi._ordinalParse=pi,mi.preparse=gn,mi.postformat=gn,mi._relativeTime=hi,mi.relativeTime=vn,mi.pastFuture=yn,mi.set=bn,mi.months=W,mi._months=Ar,mi.monthsShort=G,mi._monthsShort=Or,mi.monthsParse=K,mi._monthsRegex=Rr,mi.monthsRegex=ee,mi._monthsShortRegex=Nr,mi.monthsShortRegex=X,mi.week=Ht,mi._week=Qr,mi.firstDayOfYear=Vt,mi.firstDayOfWeek=qt,mi.weekdays=Wt,mi._weekdays=ei,mi.weekdaysMin=Kt,mi._weekdaysMin=ni,mi.weekdaysShort=Gt,mi._weekdaysShort=ti,mi.weekdaysParse=Zt,mi.isPM=on,mi._meridiemParse=ri,mi.meridiem=an,x("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===g(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),e.lang=ie("moment.lang is deprecated. Use moment.locale instead.",x),e.langData=ie("moment.langData is deprecated. Use moment.localeData instead.",k);var gi=Math.abs,vi=Fn("ms"),yi=Fn("s"),bi=Fn("m"),$i=Fn("h"),wi=Fn("d"),xi=Fn("w"),Ci=Fn("M"),ki=Fn("y"),Ei=Ln("milliseconds"),Si=Ln("seconds"),_i=Ln("minutes"),Mi=Ln("hours"),Ti=Ln("days"),Di=Ln("months"),Ai=Ln("years"),Oi=Math.round,Ni={s:45,m:45,h:22,d:26,M:11},Ri=Math.abs,Ii=Ne.prototype;return Ii.abs=_n,Ii.add=Tn,Ii.subtract=Dn,Ii.as=In,Ii.asMilliseconds=vi,Ii.asSeconds=yi,Ii.asMinutes=bi,Ii.asHours=$i,Ii.asDays=wi,Ii.asWeeks=xi,Ii.asMonths=Ci,Ii.asYears=ki,Ii.valueOf=Pn,Ii._bubble=On,Ii.get=jn,Ii.milliseconds=Ei,Ii.seconds=Si,Ii.minutes=_i,Ii.hours=Mi,Ii.days=Ti,Ii.weeks=Un,Ii.months=Di,Ii.years=Ai,Ii.humanize=zn,Ii.toISOString=Bn,Ii.toString=Bn,Ii.toJSON=Bn,Ii.locale=bt,Ii.localeData=$t,Ii.toIsoString=ie("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Bn),Ii.lang=Jr,R("X",0,0,"unix"),R("x",0,0,"valueOf"),L("x",hr),L("X",vr),V("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),V("x",function(e,t,n){n._d=new Date(g(e))}),e.version="2.11.1",function(e){Yn=e}(Te),e.fn=ci,e.min=Ae,e.max=Oe,e.now=Br,e.utc=a,e.unix=cn,e.months=xn,e.isDate=n,e.locale=x,e.invalid=c,e.duration=Ze,e.isMoment=h,e.weekdays=kn,e.parseZone=fn,e.localeData=k,e.isDuration=Re,e.monthsShort=Cn,e.weekdaysMin=Sn,e.defineLocale=C,e.weekdaysShort=En,e.normalizeUnits=S,e.relativeTimeThreshold=Vn,e.prototype=ci,e}),define("common/bundles/vendors",["common/require","common/angular","common/angularAnimate","common/angularBootstrap","common/angular-file-upload","common/angularMocks","common/angularResource","common/angularRoute","common/angularXeditable","common/text-angular","common/ui-select","common/d3","common/lodash","common/moment"],function(){}),define("common/modules/apis",["common/angular"],function(e){"use strict";return e.module("common.apis",[])}),define("common/services/api",["common/angular","common/lodash","common/modules/apis"],function(e,t,n){"use strict";n.factory("api",["$cacheFactory","$log","$http","$httpParamSerializer","$q","$timeout",function(n,r,i,o,a,s){function l(e){return e.data.is_error?(r.error(e.data),a.reject(e.data.error_message)):e.data}function u(e){var n={options:{limit:0}};return JSON.stringify(t.merge(n,e||{}))}r.debug("api");return{extend:function(t){return e.extend(Object.create(this),t)},getAll:function(e,n,i,o,s,l,u){return r.debug("api.all"),n=n||{},l=l||"get",a.all([function(){var r=t.assign({},n,s||{},{options:t.assign({},n.options,{sort:o||"id DESC"})});return i&&(r.options.offset=(i.page-1)*i.size,r.options.limit=i.size),this.sendGET(e,l,r,u)}.bind(this)(),function(){if(!i)return a.resolve();var r=t.assign({},n,{return:"id"});return r=t.omit(r,function(e,n){return t.startsWith(n,"api.")}),this.sendGET(e,l,r,u)}.bind(this)()]).then(function(e){var n=e[0],r=i?e[1]:n;return{list:n.values,total:r.count,allIds:t.compact(r.values.map(function(e){return e.id})).join(",")}})},mockGET:function(e,t){var n=a.defer();return s(function(){n.resolve(e)},t||0),n.promise},mockPOST:function(e,t){return this.mockGET.apply(this,arguments)},sendGET:function(e,t,r,a){var s={action:t,entity:e,json:u(r),sequential:1};return!1===a&&n.get("$http").remove("/civicrm/ajax/rest?"+o(s)),i({method:"GET",url:"/civicrm/ajax/rest",cache:!0,responseType:"json",params:s}).then(l)},sendPOST:function(e,t,n){return r.debug("api.sendPOST"),i({method:"POST",url:"/civicrm/ajax/rest",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},responseType:"json",data:{json:u(n),sequential:1,entity:e,action:t},transformRequest:o}).then(l)}}}])}),define("common/services/api/appraisal",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.appraisal",["$log","api",function(e,t){return e.debug("api.appraisal"),t.extend({all:function(t,n,r){return e.debug("api.appraisal.api"),this.getAll("Appraisal",t,n,r)},create:function(t){return e.debug("api.appraisal.create"),this.sendPOST("Appraisal","create",t).then(function(e){return e.values[0]})},find:function(t){return e.debug("api.appraisal.find"),this.sendGET("Appraisal","get",{id:""+t},!1).then(function(e){return e.values[0]})}})}])}),define("common/services/api/option-group",["common/lodash","common/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("api.optionGroup",["$log","api",function(t,n){function r(t){return t.values.map(function(t){var n=e.clone(t);return n.option_group_name=n["option_group_id.name"],delete n["option_group_id.name"],n})}function i(t){return e.transform(t,function(e,t){var n=t.option_group_name;e[n]=e[n]||[],e[n].push(t)})}return t.debug("api.optionGroup"),n.extend({valuesOf:function(t,n){var o=e.isArray(t);return this.sendGET("OptionValue","get",{"option_group_id.name":{IN:o?t:[t]},is_active:"1",return:["option_group_id.name","option_group_id","id","name","label","value","weight","is_active","is_reserved"]},n).then(r).then(function(e){return o?i(e):e})}})}])}),define("common/services/api/appraisal-cycle",["common/lodash","common/modules/apis","common/services/api","common/services/api/option-group"],function(e,t){"use strict";t.factory("api.appraisal-cycle",["$q","$log","api","api.optionGroup",function(t,n,r,i){return n.debug("api.appraisal-cycle"),r.extend({all:function(e,t,r){return n.debug("api.appraisal-cycle.all"),this.getAll("AppraisalCycle",e,t,r,{"api.AppraisalCycle.getappraisalsperstep":{}})},create:function(t){return n.debug("api.appraisal-cycle.create"),this.sendPOST("AppraisalCycle","create",e.assign(t,{"api.AppraisalCycle.getappraisalsperstep":{}})).then(function(e){return e.values[0]})},find:function(e){n.debug("api.appraisal-cycle.find");var t={id:""+e,"api.AppraisalCycle.getappraisalsperstep":{}};return this.sendGET("AppraisalCycle","get",t,!1).then(function(e){return e.values[0]})},grades:function(){return n.debug("grades"),this.mockGET([{label:1,value:17},{label:2,value:74},{label:3,value:90},{label:4,value:30}])},statuses:function(){return n.debug("api.appraisal-cycle.statuses"),i.valuesOf("appraisal_status")},statusOverview:function(e){return n.debug("api.appraisal-cycle.statusOverview"),this.sendGET("AppraisalCycle","getstatusoverview",e).then(function(e){return e.values})},update:function(t){return n.debug("api.appraisal-cycle.update"),this.sendPOST("AppraisalCycle","create",e.assign(t,{"api.AppraisalCycle.getappraisalsperstep":{}})).then(function(e){return e.values[0]})},total:function(e){return n.debug("api.appraisal-cycle.total"),this.sendGET("AppraisalCycle","getcount",e||{}).then(function(e){return e.result})},types:function(){return n.debug("api.appraisal-cycle.types"),i.valuesOf("appraisal_cycle_type")}})}])}),define("common/services/api/contact-job-role-api.api",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("ContactJobRoleAPI",["$log","api",function(e,t){return e.debug("ContactJobRoleAPI"),t.extend({all:function(t,n,r,i){return e.debug("ContactJobRoleAPI.all()"),this.getAll("ContactHrJobRoles",t,n,r,i)}})}])}),define("common/bundles/apis",["common/services/api/appraisal","common/services/api/appraisal-cycle","common/services/api/contact-job-role-api.api","common/services/api/option-group"],function(){}),define("common/modules/services",["common/angular","common/angular-file-upload"],function(e){"use strict";return e.module("common.services",["angularFileUpload"])}),define("common/services/before-hash-query-params.service",["common/lodash","common/modules/services"],function(e,t){"use strict";t.factory("beforeHashQueryParams",["$log","$window",function(t,n){function r(e){var t=e||n.location.href,r=o(t);return-1===r.indexOf("?")?{}:i(a(r))}function i(t){return t.length?e.transform(t,function(e,t){var n=t.split("=");n[0]&&(e[n[0]]=n[1]?decodeURI(n[1]):null)},{}):{}}function o(e){var t=e.indexOf("#");return e.substring(0,-1!==t?t:e.length)}function a(e){var t=e.indexOf("?");return e.substr(t+1).split("&")}return t.debug("Service: beforeHashQueryParams"),{parse:r}}])}),function(e){define("common/services/check-permissions",["common/lodash","common/modules/services"],function(t,n){"use strict";n.factory("checkPermissions",["$q",function(n){return function(r){return r=t.isArray(r)?r:[r],n.resolve(r.every(function(t){return e.checkPerm(t)}))}}])})}(CRM),function(e){define("common/services/crm-ang.service",["common/lodash","common/modules/services"],function(t,n){"use strict";function r(t,n){return e.loadForm(t,n)}n.factory("crmAngService",function(){return{loadForm:r}})})}(CRM),define("common/services/detect-device.service",["common/modules/services"],function(e){"use strict";e.factory("detectDevice",[function(){return{isMobile:function(){return document.getElementsByTagName("body")[0].classList.contains("mobile")}}}])}),define("common/services/dom-event-trigger",["common/modules/services"],function(e){"use strict";!function(t){e.factory("DOMEventTrigger",function(){return function(e,n){t(document).trigger(e,n)}})}(CRM.$)}),define("common/services/file-mime-types",["common/lodash","common/modules/services"],function(e,t){"use strict";t.factory("fileMimeTypes",["$q",function(e){var t={txt:"plain",png:"png",jpeg:"jpeg",bmp:"bmp",gif:"gif",pdf:"pdf",doc:"msword",docx:"vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"vnd.ms-excel",xlsx:"vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"vnd.ms-powerpoint",pptx:"vnd.openxmlformats-officedocument.presentationml.presentation"};return{getMimeTypeFor:function(n){return e.resolve(t[n])}}}])}),define("common/services/file-upload",["common/modules/services","common/lodash","common/angular-file-upload"],function(e,t){"use strict";e.factory("FileUpload",["$q","$log","FileUploader",function(e,n,r){function i(e){throw new Error(e+" missing from parameter")}function o(e,t,r,i){n.error(" ===== Item Error: "+r+" ======"),n.error(" ===== - item ======"),n.error(e),n.error(" ===== - response ======"),n.error(t),n.error(" ===== - headers ======"),n.error(i)}function a(e){return t.defaults(e,{allowedMimeTypes:{txt:"plain",png:"png",jpeg:"jpeg",bmp:"bmp",gif:"gif",pdf:"pdf"},url:"/civicrm/ajax/attachment",queueLimit:1})}return{uploader:function(n){var s,l,u,c=[];return n?(n=a(n),s=new r({url:n.url,queueLimit:+n.queueLimit,onCompleteItem:function(e,t){c.push(t)},onCompleteAll:function(){u.resolve(c)},onErrorItem:function(e){o.apply(null,arguments),u.reject("Could not upload file: "+e.file.name)},formData:[{entity_table:n.entityTable||i("entityTable"),crm_attachment_token:n.crmAttachmentToken||i("crmAttachmentToken")}],filters:[{name:"fileFormatFilter",fn:function(e){var r=e.type.slice(e.type.lastIndexOf("/")+1);return t.includes(t.values(n.allowedMimeTypes),r)}}]}),s.uploadAll=function(){return l=s.uploadAll,function(n){return u=e.defer(),s.onBeforeUploadItem=function(e){t.each(n,function(n,r){var i={};i[t.snakeCase(r)]=n,e.formData.push(i)})},l.apply(s),u.promise}}(),s):i("custom settings")}}}])}),define("common/services/file.service",["common/modules/services"],function(e){"use strict";e.factory("fileService",["$http","$window","$log",function(e,t,n){return n.debug("Service: fileService"),{openFile:function(n){return e.get(n.url,{responseType:"arraybuffer"}).success(function(e){var r=new Blob([e],{type:n.fileType});t.navigator.msSaveOrOpenBlob?t.navigator.msSaveOrOpenBlob(r,n.name):t.open(URL.createObjectURL(r),"_blank")})}}}])}),define("common/services/hr-settings",["common/modules/services"],function(e){"use strict";e.factory("HR_settings",function(){return{DATE_FORMAT:null}})}),function(e){define("common/services/notification.service",["common/lodash","common/modules/services"],function(t,n){"use strict";n.factory("notificationService",function(){return t(["alert","success","info","error"]).map(function(t){return[t,function(n,r,i){return e.alert(r,n,t,i)}]}).zipObject().value()})})}(CRM),define("common/services/pub-sub",["common/modules/services"],function(e){"use strict";var t=Object.create(null);e.factory("pubSub",["$rootScope",function(e){return{subscribe:function(n,r){var i;return t[n]=t[n]||[],r.$rootScope=e,i=t[n].push(r)-1,{remove:function(){delete t[n][i]}}},publish:function(e,n){t[e]&&(n=void 0!=n?n:{},t[e].forEach(function(e){e.$rootScope.$applyAsync(function(){e(n)})}))}}}])}),define("common/bundles/services",["common/services/before-hash-query-params.service","common/services/check-permissions","common/services/crm-ang.service","common/services/detect-device.service","common/services/dom-event-trigger","common/services/file-mime-types","common/services/file-upload","common/services/file.service","common/services/hr-settings","common/services/notification.service","common/services/pub-sub"],function(){}),define("common/modules/components",["common/angular"],function(e){return e.module("common.components",[])}),define("common/components/heatmap.component",["common/lodash","common/moment","common/modules/components"],function(e,t,n){function r(){function n(e){e.values&&(u(),l(),c())}function r(){return Object.values(d.values).filter(function(e){return!1!==e})}function i(e,t){return e.reduce(function(e,n){return Math.abs(n.value-t)');r(n,t),e.after(n)}function r(e,n){function r(){n.isOpen=!0,n.$apply()}t.isMobile()||(e.on("click",r),n.$on("$destroy",function(){e.off("click",r)}))}var i=e[0],o=i.compile;return i.compile=function(){var e=o.apply(this,arguments);return function(t,i,o){e.apply(this,arguments),n(i,t),r(i,t)}},e}]}),define("common/decorators/uib-datepicker-mobile-version.decorator",["common/moment","common/services/detect-device.service"],function(e){"use strict";return["$delegate","detectDevice",function(t,n){function r(t){return t?e(t).format("Y-MM-DD"):""}var i=t[0],o=i.compile;return i.require=["ngModel","uibDatepickerPopup"],i.compile=function(){var e=o.apply(this,arguments);return function(t,i,o,a){n.isMobile()?(i.prop("type","date"),o.ngReadonly=!1,a[0].$formatters.push(function(e){return r(e)}),t.$watch("datepickerOptions.minDate",function(e){o.$set("min",r(e))}),t.$watch("datepickerOptions.maxDate",function(e){o.$set("max",r(e))})):e.apply(this,arguments)}},t}]}),define("common/decorators/xeditable-disable-calendar-icon.decorator",[],function(){"use strict";return["$delegate",function(e){var t=e[0],n=t.compile;return t.compile=function(){var e=n.apply(this,arguments);return function(t,n,r){e.apply(this,arguments),r.eShowCalendarButton=!1}},e}]}),define("common/decorators/ui-bootstrap/uib-tabset",[],function(){"use strict";return["$delegate",function(e){return e[0].bindToController.customHeaderClass="@",e}]}),define("common/decorators/ui-bootstrap/uib-modal.decorator",["common/angular"],function(e){"use strict";return["$delegate","$document",function(e,t){function n(){var e,n=t.find("body, html");return n.addClass("chr_scroll-lock"),e=r.apply(this,arguments),e.closed.then(function(){t.find(".modal-dialog").length||n.removeClass("chr_scroll-lock")}),e}var r=e.open;return e.open=n,e}]}),define("common/modules/templates",["common/angular"],function(e){"use strict";return e.module("common.templates",[]).run(["$templateCache",function(e){e.put("dialog.html",'\n\n\n'),e.put("help-text.html",'\n'),e.put("loading.html",'
    \n
    \n
    \n
    \n'),e.put("time-amount-picker.html",'
    \n
    \n \n \n
    \n h\n
    \n \n \n
    \n m\n
    \n'),e.put("timepicker-select.html",'\n\n'),e.put("civihr-ui-select/choices.tpl.html",'
      \n
    • \n
      \n
        \n
      • \n
        \n
      • \n
      \n
    • \n
    \n'),e.put("civihr-ui-select/match-multiple.tpl.html",'\n
  • \n \n \n
  • \n\n'),e.put("civihr-ui-select/match.tpl.html",'\n {{$select.contactList ? \'-select-\' : $select.placeholder}}\n \n \n \n\n'),e.put("civihr-ui-select/select-contacts-multiple.tpl.html",'
    \n
    \n
      \n \n
    • \n \n
    • \n
    \n\n \n\n \n
    \n
    \n'),e.put("civihr-ui-select/select-contacts.tpl.html",'
    \n
    \n \n
    \n'),e.put("civihr-ui-select/select-multiple.tpl.html",'
    \n
    \n
      \n \n
    • \n \n
    • \n
    \n \n
    \n
    \n'),e.put("civihr-ui-select/select.tpl.html",'
    \n
    \n \n
    \n'),e.put("components/heatmap.html",'
      \n
    • \n {{day.name.short}}\n
    • \n
    \n'),e.put("contact-actions/contact-actions.html",'
    \n \n \n
    \n'),e.put("contact-actions/modals/form.html",'
    \n \n \n \n
    \n')}])}),define("common/modules/controllers",["common/angular","common/angularBootstrap","common/modules/apis"],function(e){"use strict";return e.module("common.controllers",["ui.bootstrap","common.apis"])}),define("common/modules/directives",["common/angular","common/decorators/ui-select-focus.decorator","common/decorators/uib-datepicker-calendar-icon.decorator","common/decorators/uib-datepicker-mobile-version.decorator","common/decorators/xeditable-disable-calendar-icon.decorator","common/decorators/ui-bootstrap/uib-tabset","common/decorators/ui-bootstrap/uib-modal.decorator","common/angularBootstrap","common/angularXeditable","common/ui-select","common/modules/templates","common/modules/controllers","common/modules/services","common/modules/apis"],function(e,t,n,r,i,o,a){"use strict";return e.module("common.directives",["common.templates","common.controllers","ui.select","ui.bootstrap","xeditable"]).config(["$provide",function(e){e.decorator("uibDatepickerPopupDirective",r),e.decorator("uibDatepickerPopupDirective",n),e.decorator("uibTabsetDirective",o),e.decorator("$uibModal",a),e.decorator("editableBsdateDirective",i),e.decorator("uiSelectDirective",t)}]).run(["$templateCache",function(e){var t="uib/template/tabs/tabset.html",n=jQuery(e.get(t));n.find("ul").addClass("{{tabset.customHeaderClass}}"),e.put(t,n.wrap("
    ").parent().html())}])}),define("common/services/api/contact-actions",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.contactActions",["$q","api",function(e,t){function n(e,n){return t.sendGET(e,"getoptions",{field:n,context:"search"}).then(function(e){return e.values})}function r(e){return t.sendGET("UFField","get",{uf_group_id:e,is_active:!0}).then(function(e){return e.values})}function i(n,r){return e(function(e,i){if(r.contact_type=n,r.email)return t.sendGET("CustomField","get",{return:["id"],custom_group_id:"Emergency_Contacts",name:"email"}).then(function(t){r["custom_"+t.id]=r.email,delete r.email,e()});e()}).then(function(){return t.sendPOST("Contact","create",r).then(function(e){return e.values[0]})})}return t.extend({getOptions:{forContactType:function(){return n.call(this,"Contact","contact_type")},forGroup:function(){return n.call(this,"GroupContact","group_id")},forTag:function(){return n.call(this,"EntityTag","tag_id")},forStateProvince:function(){return n.call(this,"Address","state_province_id")},forCountry:function(){return n.call(this,"Address","country_id")},forGender:function(){return n.call(this,"Contact","gender_id")},forDeceased:function(){return n.call(this,"Contact","is_deceased")}},save:{newIndividual:function(e){return i.call(this,"Individual",e)},newOrganization:function(e){return i.call(this,"Organization",e)},newHousehold:function(e){return i.call(this,"Household",e)}},getFormFields:{forNewIndividual:function(){return r.call(this,"new_individual")},forNewOrganization:function(){return r.call(this,"new_organization")},forNewHousehold:function(){return r.call(this,"new_household")}}})}])}),define("common/controllers/contact-actions/modal-ctrl",[],function(){"use strict";return function(e,t){this.errorMsg="",this.loading=!0,this.formFields=[],this.init=function(e){e().then(function(e){this.loading=!1,this.formFields=e}.bind(this)).catch(function(){this.loading=!1,this.errorMsg="Error while loading form fields"}.bind(this))},this.cancel=function(){t.dismiss("cancel")},this.save=function(n,r){this.loading=!0,n(this.formFields.reduce(function(e,t){return e[t.field_name]=t.value,e},{})).then(function(n){this.loading=!1,e.$broadcast(r,n),t.dismiss("cancel")}.bind(this)).catch(function(){this.loading=!1,this.errorMsg="Error while saving data"}.bind(this))}}}),define("common/controllers/contact-actions/new-individual-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Individual",i.init(r.getFormFields.forNewIndividual),i.submit=function(){i.save(r.save.newIndividual,"newIndividualCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewIndividualModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/new-household-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Household",i.init(r.getFormFields.forNewHousehold),i.submit=function(){i.save(r.save.newHousehold,"newHouseholdCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewHouseholdModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/new-organization-ctrl",["common/modules/controllers","common/controllers/contact-actions/modal-ctrl","common/services/api/contact-actions"],function(e,t){"use strict";function n(e,n,r){var i=this;t.call(i,e,n),i.title="New Organization",i.init(r.getFormFields.forNewOrganization),i.submit=function(){i.save(r.save.newOrganization,"newOrganizationCreated")}}n.prototype=Object.create(t.prototype),n.prototype.constructor=n,e.controller("NewOrganizationModalCtrl",["$rootScope","$uibModalInstance","api.contactActions",n])}),define("common/controllers/contact-actions/contact-actions-ctrl",["common/modules/controllers","common/services/api/contact-actions","common/controllers/contact-actions/new-individual-ctrl","common/controllers/contact-actions/new-household-ctrl","common/controllers/contact-actions/new-organization-ctrl"],function(e){"use strict";e.controller("ContactActionsCtrl",["$scope","$rootElement","$uibModal","api.contactActions",function(e,t,n,r){var i=this;e.$watch(function(){return i.refineSearch.selected},function(t,n){t!==n&&e.$emit("contactRefineSearch",{field:t.field?t.field.label:null,option:t.option?t.option.value:null})},!0),i.refineSearch={selected:{field:null,option:null},availableFields:[{label:"Contact Type",getOptions:r.getOptions.forContactType},{label:"Group",getOptions:r.getOptions.forGroup},{label:"Tag",getOptions:r.getOptions.forTag},{label:"State / Province",getOptions:r.getOptions.forStateProvince},{label:"Country",getOptions:r.getOptions.forCountry},{label:"Gender",getOptions:r.getOptions.forGender},{label:"Deceased",getOptions:r.getOptions.forDeceased}],availableOptions:{refresh:function(){i.refineSearch.selected.field?(this.options=null,i.refineSearch.selected.field.getOptions().then(function(e){this.options=e}.bind(this))):this.options=[]},options:[]}},i.showNewIndividualModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewIndividualModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})},i.showNewHouseholdModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewHouseholdModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})},i.showNewOrganizationModal=function(){n.open({appendTo:t.children().eq(0),controller:"NewOrganizationModalCtrl",controllerAs:"$ctrl",bindToController:!0,templateUrl:"contact-actions/modals/form.html"})}}])}),define("common/directives/prevent-animations",["common/modules/directives"],function(e){"use strict";e.directive("preventAnimations",["$animate",function(e){return{restrict:"A",link:function(t,n,r){e.enabled(n,!1)}}}])}),define("common/directives/loading",["common/modules/directives","common/directives/prevent-animations"],function(e){"use strict";e.directive("crmLoading",["$templateCache",function(e){return{scope:{show:"="},restrict:"E",replace:!0,transclude:!0,template:e.get("loading.html")}}])}),define("common/directives/contact-actions/contact-actions",["common/modules/directives","common/controllers/contact-actions/contact-actions-ctrl","common/directives/loading"],function(e){"use strict";e.directive("contactActions",[function(){return{restrict:"E",templateUrl:"contact-actions/contact-actions.html",controller:"ContactActionsCtrl",controllerAs:"$ctrl",link:function(e,t,n){e.$ctrl.refineSearchVisible=t.parent().parent()[0].hasAttribute("refine-search")}}}])}),define("common/directives/help-text.directive",["common/lodash","common/moment","common/modules/directives","common/services/notification.service"],function(e,t,n){function r(e,t){function n(){var n=e.getHelpText();t.info(e.title||r,n)}var r="Help";this.displayHelpText=n}function i(e,t,n){function r(){return t.find(".help-text").html()}e.getHelpText=r}n.directive("helpText",["$templateCache",function(e){return{restrict:"E",scope:{title:"@?"},transclude:!0,controller:r,controllerAs:"helpText",template:e.get("help-text.html"),link:i}}]),r.$inject=["$scope","notificationService"]}),define("common/directives/scroll-shadows.directive",["common/angular","common/modules/directives"],function(e,t){"use strict";function n(t,n,r){function i(){u(),a(),l(),s()}function o(){var e=f.width(),t=p+"__shadows--show-left",n=p+"__shadows--show-right",r=d.scrollLeft(),i=d.width();if(e<=i)return void d.removeClass(t+" "+n);d[r>0?"addClass":"removeClass"](t),d[r
    ').parent(),d=f.wrap('
    ').parent(),d.wrap('
    ')}var f,d,p="chr_scroll-shadows";!function(){c(),i(),o()}()}t.directive("scrollShadows",[function(){return{restrict:"A",controller:n}}]),n.$inject=["$element","$scope","$window"]}),define("common/directives/timepicker-select.directive",["common/moment","common/modules/directives"],function(e,t){"use strict";function n(t){function n(){var n=+t.timepickerSelectInterval||1,i=e.duration(t.timepickerSelectTimeFrom||"00:00"),o=e.duration(t.timepickerSelectTimeTo||"23:59");for(r.options=[];i.asMinutes()<=o.asMinutes();){var a=e.utc(i.asMilliseconds());r.options.push(a.format("HH:mm")),i.add(n,"minutes")}}var r=this;r.placeholder=t.timepickerSelectPlaceholder,r.options=[],t.$watchGroup(["timepickerSelectTimeFrom","timepickerSelectTimeTo","timepickerSelectInterval"],function(){n()})}t.directive("timepickerSelect",["$templateCache",function(e){return{scope:{timepickerSelectPlaceholder:"@",timepickerSelectTimeFrom:"<",timepickerSelectTimeTo:"<",timepickerSelectInterval:"<"},restrict:"A",controllerAs:"selector",controller:["$scope",n],template:e.get("timepicker-select.html")}}]),n.$inject=["$scope"]}),define("common/directives/time-amount-picker.directive",["common/lodash","common/modules/directives"],function(e,t){"use strict";function n(t){function n(){var e=Math.floor(c);for(d.hoursOptions=[];e<=f;)d.hoursOptions.push(e),e++}function r(){var e,t,n,r=0;for(d.minutesOptions=[];r<60;)t=+d.selectedHours===Math.floor(c)&&rf%1*60,e=t||n,!e&&d.minutesOptions.push(r),r+=u;l()}function i(){u=+t.interval||1,c=isNaN(+t.minAmount)?0:+t.minAmount,f=isNaN(+t.maxAmount)?24:+t.maxAmount,n(),r()}function o(){""!==d.selectedHours&&""!==d.selectedMinutes&&(t.value=+d.selectedHours+d.selectedMinutes/60)}function a(){t.$watch("disabled",function(e){d.disabled=e}),t.$watch("value",function(){s(),i()}),t.$watchGroup(["minAmount","maxAmount","interval"],function(){i()})}function s(){void 0!==t.value&&(d.selectedHours=""+Math.floor(t.value),d.selectedMinutes=""+Math.floor(t.value%1*60)),o()}function l(){d.selectedMinutese.last(d.minutesOptions)&&(d.selectedMinutes=""+e.last(d.minutesOptions))}var u,c,f,d=this;d.hoursOptions=[],d.minutesOptions=[],d.selectedHours="",d.selectedMinutes="",d.buildMinutesOptions=r,d.calculateSelectedValue=o,function(){s(),i(),a()}()}t.directive("timeAmountPicker",["$templateCache",function(e){return{scope:{minAmount:".75?Math.floor(.25*Math.ceil(e/.25))+"h":"",n=e%1&&e%1<=.75&&e%1>0?.25*Math.ceil(e%1/.25)*60+"m":"",r+t+(t&&n?" ":"")+n)}};return function(t,n){var r=void 0===t?0:parseFloat(t);if(isNaN(r))throw new Error("Value must be a number or a numeric string: "+t);return e[n](r)}})}),define("common/bundles/filters",["common/filters/time-unit-applier.filter"],function(){}),define("common/decorators/angular-date/datepicker-popup",["common/lodash"],function(e){return["$delegate","HR_settings",function(t,n){"use strict";var r=t[0].link;return t[0].compile=function(){return function(t,i,o,a){o.uibDatepickerPopup=o.uibDatepickerPopup||n.DATE_FORMAT||"yyyy-MM-dd",o.showButtonBar=o.showButtonBar||!1,t.datepickerOptions=e.assign({formatDayHeader:"E",showWeeks:!1,startingDay:1},t.datepickerOptions),r.apply(this,arguments)}},t}]}),define("common/decorators/angular-date/date-filter",[],function(){"use strict";return["$delegate",function(e){var t=e;return function(){if("E"===arguments[1]){var e=Array.prototype.slice.call(arguments);return e[1]="EEE",t.apply(this,e)[0]}return t.apply(this,arguments)}}]}),function(e){ +define("common/modules/angular-date",["common/angular","common/decorators/angular-date/datepicker-popup","common/decorators/angular-date/date-filter","common/modules/services","common/angularBootstrap","common/modules/templates"],function(t,n,r){"use strict";function i(t){var n="uib/template/datepicker/"+t+".html",r=o.get(n);r=r.replace(/glyphicon glyphicon-chevron-(left|right)/gm,"fa fa-chevron-$1"),"day"===t&&(r=function(t){return e(t).find('th[ng-if="showWeeks"]').parent().css({"border-top":"1px solid #DDD"}),e(t).prop("outerHTML")}(e.parseHTML(r))),o.put(n,r)}var o;return t.module("common.angularDate",["common.services","ui.bootstrap","common.templates"]).config(["$provide",function(e){e.decorator("uibDatepickerPopupDirective",n),e.decorator("dateFilter",r)}]).run(["$templateCache",function(e){o=e,["day","month","year"].forEach(i)}])})}(CRM.$),define("common/services/angular-date/date-format",["common/angular","common/modules/angular-date","common/services/hr-settings"],function(e,t){"use strict";t.factory("DateFormat",["$q","HR_settings",function(e,t){return{dateFormat:null,getDateFormat:function(){return this.dateFormat?e.when(this.dateFormat):e.when("dd/MM/yyyy").catch(function(){return"yyyy-MM-dd"}).then(function(e){return t.DATE_FORMAT=e,this.dateFormat=e,e}.bind(this))}}}])}),define("common/filters/angular-date/format-date",["common/moment","common/modules/angular-date","common/services/hr-settings"],function(e,t){"use strict";t.filter("formatDate",["HR_settings",function(t){var n=["DD-MM-YYYY","DD-MM-YYYY HH:mm:ss","YYYY-MM-DD","YYYY-MM-DD HH:mm:ss","DD/MM/YYYY","x","YYYY-MM-DD HH:mm:ss"];return function(r,i,o){var a,s=i||t.DATE_FORMAT||"YYYY-MM-DD",l=e(0);return r instanceof Date&&(r=e(r).format("YYYY-MM-DD HH:mm:ss")),a=e(r,n,!0),a.isValid()&&!a.isSame(l)?i===Date?a.toDate():a.format(s.toUpperCase())+("hours"===o?" "+a.format("HH:mm"):""):"Unspecified"}}])}),define("common/directives/angular-date/date-input",["common/modules/angular-date","common/filters/angular-date/format-date"],function(e){"use strict";e.directive("dateInput",["$filter",function(e){return{require:"ngModel",link:function(t,n,r,i){function o(t){var n=e("formatDate")(t);return n="Unspecified"==n?"":n}i.$formatters.push(o),i.$parsers=[]}}}])}),define("common/bundles/angular-date",["common/services/angular-date/date-format","common/filters/angular-date/format-date","common/directives/angular-date/date-input"],function(){}),define("common/modules/routers/compu-ng-route",["common/angular","common/angularRoute"],function(e){"use strict";return e.module("compuNgRoute",["ngRoute"]).config(["$routeProvider",function(t){var n=t.when;t.resolveForAll=function(e){return t.commonResolve=e,t},t.when=function(r,i){return e.extend(i.resolve||{},t.commonResolve||{}),n.call(t,r,i)}}])}),"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function r(e,t){return L(new(L(function(){},{prototype:e})),t)}function i(e){return j(arguments,function(t){t!==e&&j(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var r in e.path){if(e.path[r]!==t.path[r])break;n.push(e.path[r])}return n}function a(e){if(Object.keys)return Object.keys(e);var t=[];return j(e,function(e,n){t.push(n)}),t}function s(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,r=Number(arguments[2])||0;for(0>(r=0>r?Math.ceil(r):Math.floor(r))&&(r+=n);n>r;r++)if(r in e&&e[r]===t)return r;return-1}function l(e,t,n,r){var i,l=o(n,r),u={},c=[];for(var f in l)if(l[f].params&&(i=a(l[f].params),i.length))for(var d in i)s(c,i[d])>=0||(c.push(i[d]),u[i[d]]=e[i[d]]);return L({},u,t)}function u(e,t,n){if(!n){n=[];for(var r in e)n.push(r)}for(var i=0;i "));if(y[n]=r,I(e))g.push(n,[function(){return t.get(e)}],u);else{var i=t.annotate(e);j(i,function(e){e!==n&&l.hasOwnProperty(e)&&p(l[e],e)}),g.push(n,e,i)}v.pop(),y[n]=o}}function h(e){return P(e)&&e.then&&e.$$promises}if(!P(l))throw new Error("'invocables' must be an object");var m=a(l||{}),g=[],v=[],y={};return j(l,p),l=v=y=null,function(r,o,a){function s(){--b||($||i(y,o.$$values),p.$$values=y,p.$$promises=p.$$promises||!0,delete p.$$inheritedValues,u.resolve(y))}function l(e){p.$$failure=e,u.reject(e)}if(h(r)&&a===n&&(a=o,o=r,r=null),r){if(!P(r))throw new Error("'locals' must be an object")}else r=c;if(o){if(!h(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=f;var u=e.defer(),p=u.promise,v=p.$$promises={},y=L({},r),b=1+g.length/3,$=!1;if(N(o.$$failure))return l(o.$$failure),p;o.$$inheritedValues&&i(y,d(o.$$inheritedValues,m)),L(v,o.$$promises),o.$$values?($=i(y,d(o.$$values,m)),p.$$inheritedValues=d(o.$$values,m),s()):(o.$$inheritedValues&&(p.$$inheritedValues=d(o.$$inheritedValues,m)),o.then(s,l));for(var w=0,x=g.length;x>w;w+=3)r.hasOwnProperty(g[w])?s():function(n,i,o){function u(e){f.reject(e),l(e)}function c(){if(!N(p.$$failure))try{f.resolve(t.invoke(i,a,y)),f.promise.then(function(e){y[n]=e,s()},u)}catch(e){u(e)}}var f=e.defer(),d=0;j(o,function(e){v.hasOwnProperty(e)&&!r.hasOwnProperty(e)&&(d++,v[e].then(function(t){y[e]=t,--d||c()},u))}),d||c(),v[n]=f.promise}(g[w],g[w+1],g[w+2]);return p}},this.resolve=function(e,t,n,r){return this.study(e)(t,n,r)}}function g(e,t,n){this.fromConfig=function(e,t,n){return N(e.template)?this.fromString(e.template,t):N(e.templateUrl)?this.fromUrl(e.templateUrl,t):N(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return R(e)?e(t):e},this.fromUrl=function(n,r){return R(n)&&(n=n(r)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,r){return n.invoke(e,null,r||{params:t})}}function v(e,t,i){function o(t,n,r,i){if(g.push(t),h[t])return h[t];if(!/^\w+(-+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(m[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return m[t]=new H.Param(t,n,r,i),m[t]}function a(e,t,n,r){var i=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:i=["(",")"+(r?"?":"")];break;case!0:i=["?(",")?"];break;default:i=["("+n+"|",")?"]}return o+i[0]+t+i[1]}function s(i,o){var a,s,l,u,c;return a=i[2]||i[3],c=t.params[a],l=e.substring(d,i.index),s=o?i[4]:i[4]||("*"==i[1]?".*":null),u=H.type(s||"string")||r(H.type("string"),{pattern:new RegExp(s,t.caseInsensitive?"i":n)}),{id:a,regexp:s,segment:l,type:u,cfg:c}}t=L({params:{}},P(t)?t:{});var l,u=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,c=/([:]?)([\w\[\]-]+)|\{([\w\[\]-]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,f="^",d=0,p=this.segments=[],h=i?i.params:{},m=this.params=i?i.params.$$new():new H.ParamSet,g=[];this.source=e;for(var v,y,b;(l=u.exec(e))&&(v=s(l,!1),!(v.segment.indexOf("?")>=0));)y=o(v.id,v.type,v.cfg,"path"),f+=a(v.segment,y.type.pattern.source,y.squash,y.isOptional),p.push(v.segment),d=u.lastIndex;b=e.substring(d);var $=b.indexOf("?");if($>=0){var w=this.sourceSearch=b.substring($);if(b=b.substring(0,$),this.sourcePath=e.substring(0,d+$),w.length>0)for(d=0;l=c.exec(w);)v=s(l,!0),y=o(v.id,v.type,v.cfg,"search"),d=u.lastIndex}else this.sourcePath=e,this.sourceSearch="";f+=a(b)+(!1===t.strict?"/?":"")+"$",p.push(b),this.regexp=new RegExp(f,t.caseInsensitive?"i":n),this.prefix=p[0],this.$$paramNames=g}function y(e){L(this,e)}function b(){function e(e){return null!=e?e.toString().replace(/\//g,"%2F"):e}function i(e){return null!=e?e.toString().replace(/%2F/g,"/"):e}function o(){return{strict:m,caseInsensitive:d}}function l(e){return R(e)||F(e)&&R(e[e.length-1])}function u(){for(;x.length;){var e=x.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend($[e.name],f.invoke(e.def))}}function c(e){L(this,e||{})}H=this;var f,d=!1,m=!0,g=!1,$={},w=!0,x=[],C={string:{encode:e,decode:i,is:function(e){return null==e||!N(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return N(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};b.$$getDefaultValue=function(e){if(!l(e.value))return e.value;if(!f)throw new Error("Injectable functions cannot be called at configuration time");return f.invoke(e.value)},this.caseInsensitive=function(e){return N(e)&&(d=e),d},this.strictMode=function(e){return N(e)&&(m=e),m},this.defaultSquashPolicy=function(e){if(!N(e))return g;if(!0!==e&&!1!==e&&!I(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return g=e,e},this.compile=function(e,t){return new v(e,L(o(),t))},this.isMatcher=function(e){if(!P(e))return!1;var t=!0;return j(v.prototype,function(n,r){R(n)&&(t=t&&N(e[r])&&R(e[r]))}),t},this.type=function(e,t,n){if(!N(t))return $[e];if($.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return $[e]=new y(L({name:e},t)),n&&(x.push({name:e,def:n}),w||u()),this},j(C,function(e,t){$[t]=new y(L({name:t},e))}),$=r($,{}),this.$get=["$injector",function(e){return f=e,w=!1,u(),j(C,function(e,t){$[t]||($[t]=new y(e))}),this}],this.Param=function(e,t,r,i){function o(){if(!f)throw new Error("Injectable functions cannot be called at configuration time");var e=f.invoke(r.$$fn);if(null!==e&&e!==n&&!d.type.is(e))throw new Error("Default value ("+e+") for parameter '"+d.id+"' is not an instance of Type ("+d.type.name+")");return e}function u(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=h(p(d.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),N(e)?d.type.$normalize(e):o()}function c(){return"{Param:"+e+" "+t+" squash: '"+b+"' optional: "+v+"}"}var d=this;r=function(e){var t=P(e)?a(e):[];return-1===s(t,"value")&&-1===s(t,"type")&&-1===s(t,"squash")&&-1===s(t,"array")&&(e={value:e}),e.$$fn=l(e.value)?e.value:function(){return e.value},e}(r),t=function(t,n,r){if(t.type&&n)throw new Error("Param '"+e+"' has two type configurations.");return n||(t.type?t.type instanceof y?t.type:new y(t.type):"config"===r?$.any:$.string)}(r,t,i);var m=function(){var t={array:"search"===i&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return L(t,n,r).array}();t=m?t.$asArray(m,"search"===i):t,"string"!==t.name||m||"path"!==i||r.value!==n||(r.value="");var v=r.value!==n,b=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!N(n)||null==n)return g;if(!0===n||I(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,v),w=function(e,t,r,i){var o,a,l=[{from:"",to:r||t?n:""},{from:null,to:r||t?n:""}];return o=F(e.replace)?e.replace:[],I(i)&&o.push({from:i,to:n}),a=h(o,function(e){return e.from}),p(l,function(e){return-1===s(a,e.from)}).concat(o)}(r,m,v,b);L(this,{id:e,type:t,location:i,array:m,squash:b,replace:w,isOptional:v,value:u,dynamic:n,config:r,toString:c})},c.prototype={$$new:function(){return r(this,L(new c,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,r=a(c.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),j(t,function(t){j(a(t),function(t){-1===s(e,t)&&-1===s(r,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return j(n.$$keys(),function(r){t[r]=n[r].value(e&&e[r])}),t},$$equals:function(e,t){var n=!0,r=this;return j(r.$$keys(),function(i){var o=e&&e[i],a=t&&t[i];r[i].type.equals(o,a)||(n=!1)}),n},$$validates:function(e){var r,i,o,a,s,l=this.$$keys();for(r=0;ri;i++)if(t(u[i]))return;c&&t(c)}}function p(){return l=l||i.$on("$locationChangeSuccess",d)}var h,m=a.baseHref(),g=r.url();return f||p(),{sync:function(){d()},listen:function(){return p()},update:function(e){return e?void(g=r.url()):void(r.url()!==g&&(r.url(g),r.replace()))},push:function(e,t,i){var o=e.format(t||{});null!==o&&t&&t["#"]&&(o+="#"+t["#"]),r.url(o),h=i&&i.$$avoidResync?r.url():n,i&&i.replace&&r.replace()},href:function(n,i,o){if(!n.validates(i))return null;var a=e.html5Mode();t.isObject(a)&&(a=a.enabled);var l=n.format(i);if(o=o||{},a||null===l||(l="#"+e.hashPrefix()+l),null!==l&&i&&i["#"]&&(l+="#"+i["#"]),l=s(l,a,o.absolute),!o.absolute||!l)return l;var u=!a&&l?"/":"",c=r.port();return c=80===c||443===c?"":":"+c,[r.protocol(),"://",r.host(),c,u,l].join("")}}}var l,u=[],c=null,f=!1;this.rule=function(e){if(!R(e))throw new Error("'rule' must be a function");return u.push(e),this},this.otherwise=function(e){if(I(e)){var t=e;e=function(){return t}}else if(!R(e))throw new Error("'rule' must be a function");return c=e,this},this.when=function(e,t){var n,s=I(t);if(I(e)&&(e=r.compile(e)),!s&&!R(t)&&!F(t))throw new Error("invalid 'handler' in when()");var l={matcher:function(e,t){return s&&(n=r.compile(t),t=["$match",function(e){return n.format(e)}]),L(function(n,r){return a(n,t,e.exec(r.path(),r.search()))},{prefix:I(e.prefix)?e.prefix:""})},regex:function(e,t){if(e.global||e.sticky)throw new Error("when() RegExp must not be global or sticky");return s&&(n=t,t=["$match",function(e){return o(n,e)}]),L(function(n,r){return a(n,t,e.exec(r.path()))},{prefix:i(e)})}},u={matcher:r.isMatcher(e),regex:e instanceof RegExp};for(var c in u)if(u[c])return this.rule(l[c](e,t));throw new Error("invalid 'what' in when()")},this.deferIntercept=function(e){e===n&&(e=!0),f=e},this.$get=s,s.$inject=["$location","$rootScope","$injector","$browser"]}function w(e,i){function o(e){return 0===e.indexOf(".")||0===e.indexOf("^")}function d(e,t){if(!e)return n;var r=I(e),i=r?e:e.name;if(o(i)){if(!t)throw new Error("No reference point given for path '"+i+"'");t=d(t);for(var a=i.split("."),s=0,l=a.length,u=t;l>s;s++)if(""!==a[s]||0!==s){if("^"!==a[s])break;if(!u.parent)throw new Error("Path '"+i+"' not valid for state '"+t.name+"'");u=u.parent}else u=t;a=a.slice(s).join("."),i=u.name+(u.name&&a?".":"")+a}var c=E[i];return!c||!r&&(r||c!==e&&c.self!==e)?n:c}function p(e,t){S[e]||(S[e]=[]),S[e].push(t)}function m(e){for(var t=S[e]||[];t.length;)g(t.shift())}function g(t){t=r(t,{self:t,resolve:t.resolve||{},toString:function(){return this.name}});var n=t.name;if(!I(n)||n.indexOf("@")>=0)throw new Error("State must have a valid name");if(E.hasOwnProperty(n))throw new Error("State '"+n+"'' is already defined");var i=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):I(t.parent)?t.parent:P(t.parent)&&I(t.parent.name)?t.parent.name:"";if(i&&!E[i])return p(i,t.self);for(var o in M)R(M[o])&&(t[o]=M[o](t,M.$delegates[o]));return E[n]=t,!t[_]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){k.$current.navigable==t&&u(e,n)||k.transitionTo(t,e,{inherit:!0,location:!1})}]),m(n),t}function v(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=k.$current.name.split("."),r=0,i=t.length;i>r;r++)"*"===t[r]&&(n[r]="*");return"**"===t[0]&&(n=n.slice(s(n,t[1])),n.unshift("**")),"**"===t[t.length-1]&&(n.splice(s(n,t[t.length-2])+1,Number.MAX_VALUE),n.push("**")),t.length==n.length&&n.join("")===t.join("")}function b(e,t){return I(e)&&!N(t)?M[e]:R(t)&&I(e)?(M[e]&&!M.$delegates[e]&&(M.$delegates[e]=M[e]),M[e]=t,this):this}function $(e,t){return P(e)?t=e:t.name=e,g(t),this}function w(e,i,o,s,f,p,m,g,b){function $(t,n,r,o){var a=e.$broadcast("$stateNotFound",t,n,r);if(a.defaultPrevented)return m.update(),T;if(!a.retry)return null;if(o.$retry)return m.update(),D;var s=k.transition=i.when(a.retry);return s.then(function(){return s!==k.transition?S:(t.options.$retry=!0,k.transitionTo(t.to,t.toParams,t.options))},function(){return T}),m.update(),s}function w(e,n,r,a,l,u){function d(){var n=[];return j(e.views,function(r,i){var a=r.resolve&&r.resolve!==e.resolve?r.resolve:{};a.$template=[function(){return o.load(i,{view:r,locals:l.globals,params:p,notify:u.notify})||""}],n.push(f.resolve(a,l.globals,l.resolve,e).then(function(n){if(R(r.controllerProvider)||F(r.controllerProvider)){var o=t.extend({},a,l.globals);n.$$controller=s.invoke(r.controllerProvider,null,o)}else n.$$controller=r.controller;n.$$state=e,n.$$controllerAs=r.controllerAs,l[i]=n}))}),i.all(n).then(function(){return l.globals})}var p=r?n:c(e.params.$$keys(),n),h={$stateParams:p};l.resolve=f.resolve(e.resolve,h,l.resolve,e);var m=[l.resolve.then(function(e){l.globals=e})];return a&&m.push(a),i.all(m).then(d).then(function(e){return l})}var S=i.reject(new Error("transition superseded")),M=i.reject(new Error("transition prevented")),T=i.reject(new Error("transition aborted")),D=i.reject(new Error("transition failed"));return C.locals={resolve:null,globals:{$stateParams:{}}},k={params:{},current:C.self,$current:C,transition:null},k.reload=function(e){return k.transitionTo(k.current,p,{reload:e||!0,inherit:!1,notify:!0})},k.go=function(e,t,n){return k.transitionTo(e,t,L({inherit:!0,relative:k.$current},n))},k.transitionTo=function(t,n,o){n=n||{},o=L({location:!0,inherit:!1,relative:null,notify:!0,reload:!1,$retry:!1},o||{});var a,u=k.$current,f=k.params,h=u.path,g=d(t,o.relative),v=n["#"];if(!N(g)){var y={to:t,toParams:n,options:o},b=$(y,u.self,f,o);if(b)return b;if(t=y.to,n=y.toParams,o=y.options,g=d(t,o.relative),!N(g)){if(!o.relative)throw new Error("No such state '"+t+"'");throw new Error("Could not resolve '"+t+"' from state '"+o.relative+"'")}}if(g[_])throw new Error("Cannot transition to abstract state '"+t+"'");if(o.inherit&&(n=l(p,n||{},k.$current,g)),!g.params.$$validates(n))return D;n=g.params.$$values(n),t=g;var E=t.path,T=0,A=E[T],O=C.locals,R=[];if(o.reload){if(I(o.reload)||P(o.reload)){if(P(o.reload)&&!o.reload.name)throw new Error("Invalid reload state object");var F=!0===o.reload?h[0]:d(o.reload);if(o.reload&&!F)throw new Error("No such reload state '"+(I(o.reload)?o.reload:o.reload.name)+"'");for(;A&&A===h[T]&&A!==F;)O=R[T]=A.locals,T++,A=E[T]}}else for(;A&&A===h[T]&&A.ownParams.$$equals(n,f);)O=R[T]=A.locals,T++,A=E[T];if(x(t,n,u,f,O,o))return v&&(n["#"]=v),k.params=n,U(k.params,p),o.location&&t.navigable&&t.navigable.url&&(m.push(t.navigable.url,n,{$$avoidResync:!0,replace:"replace"===o.location}),m.update(!0)),k.transition=null,i.when(k.current);if(n=c(t.params.$$keys(),n||{}),o.notify&&e.$broadcast("$stateChangeStart",t.self,n,u.self,f).defaultPrevented)return e.$broadcast("$stateChangeCancel",t.self,n,u.self,f),m.update(),M;for(var j=i.when(O),H=T;H=T;r--)a=h[r],a.self.onExit&&s.invoke(a.self.onExit,a.self,a.locals.globals),a.locals=null;for(r=T;r=0?i:i+"@"+(o?o.state.name:"")}function _(e,t){var n,r=e.match(/^\s*({[^}]*})\s*$/);if(r&&(e=t+"("+r[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function M(e){var t=e.parent().inheritedData("$uiView");return t&&t.state&&t.state.name?t.state:void 0}function T(e,n){var r=["location","inherit","reload","absolute"];return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(i,o,a,s){var l=_(a.uiSref,e.current.name),u=null,c=M(o)||e.$current,f="[object SVGAnimatedString]"===Object.prototype.toString.call(o.prop("href"))?"xlink:href":"href",d=null,p="A"===o.prop("tagName").toUpperCase(),h="FORM"===o[0].nodeName,m=h?"action":f,g=!0,v={relative:c,inherit:!0},y=i.$eval(a.uiSrefOpts)||{};t.forEach(r,function(e){e in y&&(v[e]=y[e])});var b=function(n){if(n&&(u=t.copy(n)),g){d=e.href(l.state,u,v);var r=s[1]||s[0];return r&&r.$$addStateInfo(l.state,u),null===d?(g=!1,!1):void a.$set(m,d)}};l.paramExpr&&(i.$watch(l.paramExpr,function(e,t){e!==u&&b(e)},!0),u=t.copy(i.$eval(l.paramExpr))),b(),h||o.bind("click",function(t){if(!((t.which||t.button)>1||t.ctrlKey||t.metaKey||t.shiftKey||o.attr("target"))){var r=n(function(){e.go(l.state,u,v)});t.preventDefault();var i=p&&!d?1:0;t.preventDefault=function(){i--<=0&&n.cancel(r)}}})}}}function D(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs",function(t,r,i){function o(){a()?r.addClass(l):r.removeClass(l)}function a(){for(var e=0;er;r++){o=a[r];var c=this.params[o],f=n[r+1];for(i=0;ir;r++)o=a[r],u[o]=this.params[o].value(t[o]);return u},v.prototype.parameters=function(e){return N(e)?this.params[e]||null:this.$$paramNames},v.prototype.validates=function(e){return this.params.$$validates(e)},v.prototype.format=function(e){function t(e){return encodeURIComponent(e).replace(/-/g,function(e){return"%5C%"+e.charCodeAt(0).toString(16).toUpperCase()})}e=e||{};var n=this.segments,r=this.parameters(),i=this.params;if(!this.validates(e))return null;var o,a=!1,s=n.length-1,l=r.length,u=n[0];for(o=0;l>o;o++){var c=s>o,f=r[o],d=i[f],p=d.value(e[f]),m=d.isOptional&&d.type.equals(d.value(),p),g=!!m&&d.squash,v=d.type.encode(p);if(c){var y=n[o+1];if(!1===g)null!=v&&(u+=F(v)?h(v,t).join("-"):encodeURIComponent(v)),u+=y;else if(!0===g){var b=u.match(/\/$/)?/\/?(.*)/:/(.*)/;u+=y.match(b)[1]}else I(g)&&(u+=g+y)}else{if(null==v||m&&!1!==g)continue;F(v)||(v=[v]),v=h(v,encodeURIComponent).join("&"+f+"="),u+=(a?"&":"?")+f+"="+v,a=!0}}return u},y.prototype.is=function(e,t){return!0},y.prototype.encode=function(e,t){return e},y.prototype.decode=function(e,t){return e},y.prototype.equals=function(e,t){return e==t},y.prototype.$subPattern=function(){var e=this.pattern.toString();return e.substr(1,e.length-2)},y.prototype.pattern=/.*/,y.prototype.toString=function(){return"{Type:"+this.name+"}"},y.prototype.$normalize=function(e){return this.is(e)?e:this.decode(e)},y.prototype.$asArray=function(e,t){function r(e,t){function r(e,t){return function(){return e[t].apply(e,arguments)}}function i(e){return F(e)?e:N(e)?[e]:[]}function o(e){switch(e.length){case 0:return n;case 1:return"auto"===t?e[0]:e;default:return e}}function a(e){return!e}function s(e,t){return function(n){n=i(n);var r=h(n,e);return!0===t?0===p(r,a).length:o(r)}}this.encode=s(r(e,"encode")),this.decode=s(r(e,"decode")),this.is=s(r(e,"is"),!0),this.equals=function(e){return function(t,n){var r=i(t),o=i(n);if(r.length!==o.length)return!1;for(var a=0;a=":n(e.from)}:{"<=":n(e.to)}}function o(e){return e.in?{IN:e.in}:{"NOT IN":e.nin}}return{extend:function(t){return e.assign(Object.create(this),t)},compactFilters:function(t){return t?e.pick(t,function(e){return 0===e||!1===e||!!e}):null},processFilters:function(t){return t?(t=this.compactFilters(t),e.transform(t,function(e,t,n){t.from||t.to?e[n]=i(t):t.in||t.nin?e[n]=o(t):e[n]=t},{})):null}}})}),define("common/models/contact-job-role.model",["common/modules/models","common/models/model","common/instances/contact-job-role-instance.instance","common/services/api/contact-job-role-api.api"],function(e){"use strict";e.factory("ContactJobRole",["$log","Model","ContactJobRoleAPI","ContactJobRoleInstance",function(e,t,n,r){return e.debug("ContactJobRole"),t.extend({all:function(e){return n.all(e).then(function(e){return e.list.map(function(e){return r.init(e,!0)})})}})}])}),define("common/models/instances/group-instance",["common/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("GroupInstance",["ModelInstance",function(e){var t=["id","name","title","description"];return e.extend({fromAPIFilter:function(e,n,r){_.includes(t,r)&&(e[r]=this[r])}})}])}),define("common/mocks/module",["common/angular"],function(e){"use strict";return e.module("common.mocks",[])}),define("common/mocks/services/api/group-mock",["common/lodash","common/mocks/module"],function(e,t){"use strict";t.factory("api.group.mock",["$q",function(t){function n(e){var n=t.defer();return n.resolve(e),n.promise}return{all:function(e,t,r){var i,o,a;return i=r||this.mockedGroups().list,e&&(i=i.filter(function(t){return Object.keys(e).every(function(n){return t[n]===e[n]})})),t&&(o=(t.page-1)*t.size,a=o+t.size,i=i.slice(o,a)),n({list:i,total:i.length,allIds:i.map(function(e){return e.id}).join(",")})},find:function(e,t){return n(t||this.mockedGroups().list.filter(function(t){return t.id===e})[0])},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedGroups:function(){return{total:5,list:[{id:"1",name:"Administrators",title:"Administrators",description:"Contacts in this group are assigned Administrator role permissions.",is_active:"1",visibility:"User and User Admin Only",group_type:["1"],is_hidden:"0",is_reserved:"0"},{id:"2",name:"Newsletter Subscribers",title:"Newsletter Subscribers",is_active:'"1',visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"3",name:"Summer Program Volunteers",title:"Summer Program Volunteers",is_active:"1",visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"4",name:"Advisory Board",title:"Advisory Board",is_active:"1",visibility:"Public Pages",where_clause:"...",select_tables:"...",where_tables:"...",group_type:["1","2"],is_hidden:"0",is_reserved:"0"},{id:"5",name:"Case_Resources",title:"Case Resources",description:"Contacts in this group are listed with their phone number and email when viewing case. You also can send copies of case activities to these contacts.",is_active:"1",visibility:"User and User Admin Only",where_clause:"...",select_tables:"...",where_tables:"...",group_type:"2",is_hidden:"0",is_reserved:"0"}]}}}}])}),define("common/mocks/data/contact.data",[],function(){return{all:{is_error:0,version:3,count:26,values:[{id:"1",contact_id:"1",display_name:"Dr. Kiara Jensen-Parker",email:"kh.jensen-parker@testing.info",contact_type:"Individual"},{id:"2",contact_id:"2",display_name:"jacobc82@lol.co.pl",email:"cruz.v.jacob@spamalot.com",contact_type:"Individual"},{id:"3",contact_id:"3",display_name:"Mei Müller-Nielsen",email:"mz.mller-nielsen75@infomail.co.pl",contact_type:"Individual"},{id:"4",contact_id:"4",display_name:"Ms. Brigette Deforest",email:"deforest.p.brigette9@fakemail.info",contact_type:"Individual"},{id:"5",contact_id:"5",display_name:"robertsc@testing.net",email:"clintr56@mymail.org",contact_type:"Individual"},{id:"6",contact_id:"6",display_name:"Dr. Allen Samuels Sr.",email:"samuelsa@mymail.org",contact_type:"Individual"},{id:"7",contact_id:"7",display_name:"Mei Wilson",email:"wilson.u.mei59@sample.org",contact_type:"Individual"},{id:"8",contact_id:"8",display_name:"Dr. Betty Díaz",email:"dazb@sample.co.nz",contact_type:"Individual"},{id:"9",contact_id:"9",display_name:"Bob Jones-Dimitrov",email:"bobj@testmail.biz",contact_type:"Individual"},{id:"10",contact_id:"10",display_name:"Truman Samuels III",email:"trumans@spamalot.org",contact_type:"Individual"},{id:"11",contact_id:"11",display_name:"Iris Wagner",email:"iwagner75@notmail.info",contact_type:"Individual"},{id:"12",contact_id:"12",display_name:"Mr. Rosario McReynolds",email:"rosariomcreynolds@testmail.org",contact_type:"Individual"},{id:"13",contact_id:"13",display_name:"Shad Jones-Dimitrov III",email:"shadj@lol.net",contact_type:"Individual"},{id:"14",contact_id:"14",display_name:"Toby Cruz Sr.",email:"",contact_type:"Individual"},{id:"15",contact_id:"15",display_name:"lareedaz61@testing.com",email:"lareedaz61@testing.com",contact_type:"Individual"},{id:"16",contact_id:"16",display_name:"Dr. Jay Deforest",email:"jayd@fishmail.org",contact_type:"Individual"},{id:"17",contact_id:"17",display_name:"Mr. Norris Cruz",email:"norriscruz@spamalot.info",contact_type:"Individual"},{id:"18",contact_id:"18",display_name:"herminiac@fishmail.com",email:"herminiac@fishmail.com",contact_type:"Individual"},{id:"19",contact_id:"19",display_name:"Ashley Terrell",email:"terrell.ashley@testmail.info",contact_type:"Individual"},{id:"20",contact_id:"20",display_name:"Kandace Parker-Díaz",email:"parker-daz.kandace67@fishmail.co.uk",contact_type:"Individual"},{id:"21",contact_id:"21",display_name:"Nicole Samuels",email:"ng.samuels@testmail.net",contact_type:"Individual"},{id:"22",contact_id:"22",display_name:"Dr. Kandace Wattson",email:"kandacewattson@testing.info",contact_type:"Individual"},{id:"23",contact_id:"23",display_name:"Brittney Cruz",email:"cruz.brittney@spamalot.co.nz",contact_type:"Individual"},{id:"24",contact_id:"24",display_name:"Shauna Olsen",email:"",contact_type:"Individual"},{id:"202",contact_id:"202",display_name:"civihr_staff@compucorp.co.uk",email:"civihr_staff@compucorp.co.uk",contact_type:"Individual"},{id:"203",contact_id:"203",display_name:"civihr_manager@compucorp.co.uk",email:"civihr_manager@compucorp.co.uk",contact_type:"Individual"}]}}}),define("common/mocks/services/api/contact-mock",["common/lodash","common/mocks/module","common/mocks/data/contact.data"],function(e,t,n){"use strict";t.factory("api.contact.mock",["$q",function(t){function r(e){var n=t.defer();return n.resolve(e),n.promise}return{all:function(t,i,o,a,s){var l,u,c;return l=s||n.all.values,t&&(l=l.filter(function(n){return Object.keys(t).every(function(r){return null===t[r]||("display_name"===r?new RegExp(t[r],"i").test(n[r]):t[r].IN?e.includes(t[r].IN,n[r]):n[r]===t[r])})})),i&&(u=(i.page-1)*i.size,c=u+i.size,l=l.slice(u,c)),r({list:l,total:l.length,allIds:l.map(function(e){return e.id}).join(",")})},find:function(e,t){return r(t||n.all.values.filter(function(t){return t.id===e})[0])},leaveManagees:function(){return r(this.mockedContacts().list)},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedContacts:function(){var e=n.all.values;return{total:e.length,list:e.map(function(e){return e})}}}}])}),define("common/mocks/services/api/group-contact-mock",["common/lodash","common/mocks/module","common/mocks/services/api/contact-mock","common/mocks/services/api/group-mock"],function(e,t){"use strict";t.factory("api.group-contact.mock",["$q","api.contact.mock","api.group.mock",function(t,n,r){function i(t){return e.sample(t)}function o(e){var n=t.defer();return n.resolve(e),n.promise}var a=n.mockedContacts().list,s=r.mockedGroups().list;return{all:function(e,t,n){var r,i,a;return r=n||this.mockedGroupsContacts.list,e&&(r=r.filter(function(t){return Object.keys(e).every(function(n){return t[n]===e[n]})})),t&&(i=(t.page-1)*t.size,a=i+t.size,r=r.slice(i,a)),o({list:r,total:r.length,allIds:r.map(function(e){return e.id}).join(",")})},spyOnMethods:function(){e.functions(this).forEach(function(e){spyOn(this,e).and.callThrough()}.bind(this))},mockedGroupsContacts:{total:a.length,list:function(){var e=1;return a.map(function(t){return{id:""+e++,group_id:i(s).id,contact_id:t.id,status:"Added"}})}()}}}])}),define("common/models/group",["common/modules/models","common/models/model","common/models/instances/group-instance","common/mocks/services/api/group-mock","common/mocks/services/api/group-contact-mock"],function(e){"use strict";e.factory("Group",["Model","api.group.mock","api.group-contact.mock","GroupInstance",function(e,t,n,r){return e.extend({all:function(e,n){return t.all(this.processFilters(e),n).then(function(e){return e.list=e.list.map(function(e){return r.init(e,!0)}),e})},find:function(e){return t.find(e).then(function(e){return r.init(e,!0)})},contactIdsOf:function(e){return n.all({group_id:e}).then(function(e){return e.list.map(function(e){return e.contact_id})})}})}])}),define("common/models/instances/job-role-instance",["common/lodash","common/moment","common/modules/models-instances","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("JobRoleInstance",["ModelInstance","HR_settings",function(n,r){return n.extend({fromAPIFilter:function(n,i,o){var a=r.DATE_FORMAT.toUpperCase();e.endsWith(o,"_date")?n[o]=t(this[o],"YYYY-MM-DD HH:mm:ss").format(a):"api.HRJobContract.getsingle"===o?(n.contact_id=this[o].contact_id,n.job_contract_id=this[o].id):n[o]=this[o]},toAPIFilter:function(n,i,o){var a=["contact_id","job_contract_id"],s=r.DATE_FORMAT.toUpperCase();if(e.endsWith(o,"_date"))n[o]=t(this[o],s).format("YYYY-MM-DD HH:mm:ss");else{if(e.includes(a,o))return;n[o]=this[o]}}})}])}),define("common/services/api/job-role",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.job-role",["$log","api",function(e,t){return e.debug("api.jobRole"),t.extend({all:function(t,n,r,i){return e.debug("api.jobRole.api"),this.getAll("HrJobRoles",t,n,r,i)},find:function(t){return e.debug("api.jobRole.find"),this.sendGET("HRJobRole","get",{id:""+t},!1).then(function(e){return e.values[0]})}})}])}),define("common/models/job-role",["common/modules/models","common/models/model","common/models/instances/job-role-instance","common/services/api/job-role"],function(e){"use strict";e.factory("JobRole",["Model","api.job-role","JobRoleInstance",function(e,t,n){return e.extend({all:function(e,r){return t.all(this.processFilters(e),r).then(function(e){return e.list=e.list.map(function(e){return n.init(e,!0)}),e})},find:function(e){return t.find(e).then(function(e){return n.init(e,!0)})}})}])}),define("common/services/api/contact",["common/modules/apis","common/services/api"],function(e){"use strict";e.factory("api.contact",["$log","api",function(e,t){return e.debug("api.contact"),t.extend({all:function(t,n,r,i){return e.debug("api.contact.api"),this.getAll("Contact",t,n,r,i)},find:function(t){return e.debug("api.contact.find"),this.sendGET("Contact","get",{id:""+t},!1).then(function(e){return e.values[0]})},leaveManagees:function(t,n){return e.debug("api.contact.leaveManagees"),n=_.assign({},n,{managed_by:t}),this.sendGET("Contact","getleavemanagees",n).then(function(e){return e.values})}})}])}),define("common/models/instances/contact-instance",["common/modules/models-instances","common/models/instances/instance","common/services/api/contact"],function(e){"use strict";e.factory("ContactInstance",["ModelInstance","api.contact",function(e,t){return e.extend({leaveManagees:function(e){return t.leaveManagees(this.id,e)}})}])}),define("common/models/contact",["common/lodash","common/modules/models","common/models/model","common/models/contact-job-role.model","common/models/group","common/models/job-role","common/models/instances/contact-instance","common/services/api/contact"],function(e,t){"use strict";t.factory("Contact",["$q","Model","api.contact","Group","JobRole","ContactJobRole","ContactInstance",function(t,n,r,i,o,a,s){function l(t,n){return!e.isEmpty(e.intersection(e.keys(t),n))}function u(e){return a.all(e).then(function(e){return e.map(function(e){return e.contact_id})})}function c(t,n){return e(t).omit(d).omit(p).assign({id:{in:e.intersection.apply(null,n)}}).value()}function f(n){var r=t.defer(),o=[];return n=this.compactFilters(n),l(n,p)&&o.push(u(e.pick(n,p))),l(n,d)&&o.push(i.contactIdsOf(n.group_id)),e.isEmpty(o)?r.resolve(this.processFilters(n)):t.all(o).then(function(e){n=c(n,e),r.resolve(this.processFilters(n))}.bind(this)),r.promise}var d=["group_id"],p=["region","department","level_type","location"];return n.extend({all:function(e,t,n,i){return f.call(this,e).then(function(e){return e&&e.id&&!e.id.IN.length?{list:[]}:r.all(e,t,n,i)}).then(function(e){return e.list=e.list.map(function(e){return s.init(e,!0)}),e})},find:function(e){return r.find(e).then(function(e){return s.init(e,!0)})},leaveManagees:function(e,t){return f.call(this,t).then(function(t){return t&&t.id&&!t.id.IN.length?[]:r.leaveManagees(e,t)})}})}])}),define("common/models/instances/contract-instance",["common/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("ContractInstance",["ModelInstance",function(e){return e.extend({})}])}),define("common/services/api/contract",["common/lodash","common/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("api.contract",["$log","api",function(t,n){function r(t){var n=e.clone(t);return n.info=n["api.HRJobContract.getfulldetails"],delete n["api.HRJobContract.getfulldetails"],n}return t.debug("api.contract"),n.extend({all:function(e){return t.debug("ContractAPI.all"),e=e||{},e["api.HRJobContract.getfulldetails"]={jobcontract_id:"$value.id"},e.deleted=0,this.sendGET("HRJobContract","get",e,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r)})}})}])}),define("common/models/contract",["common/modules/models","common/models/model","common/models/instances/contract-instance","common/services/api/contract"],function(e){"use strict";e.factory("Contract",["$log","Model","api.contract","ContractInstance",function(e,t,n,r){return e.debug("Contract"),t.extend({all:function(e){return n.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})}})}])}),define("common/models/option-group",["common/modules/models","common/models/model","common/services/api/option-group"],function(e){"use strict";e.factory("OptionGroup",["Model","api.optionGroup",function(e,t){return e.extend({valuesOf:function(e,n){return t.valuesOf(e,n)}})}])}),function(e,t){define("common/models/session.model",["common/modules/models","common/models/model"],function(n){"use strict";n.factory("Session",["$log","$q","Model",function(n,r,i){return n.debug("Session"),i.extend({get:function(){var n={contactId:e.vars.session?e.vars.session.contact_id:t.settings.currentCiviCRMUserId};if(!n.contactId)throw new Error("Session Error: *Logged In Contact Id* is not defined");return r.resolve(n)}})}])})}(CRM,window.Drupal),define("common/bundles/models",["common/instances/contact-job-role-instance.instance","common/models/model","common/models/contact","common/models/contact-job-role.model","common/models/contract","common/models/group","common/models/job-role","common/models/option-group","common/models/session.model","common/models/instances/instance","common/models/instances/contact-instance","common/models/instances/contract-instance","common/models/instances/group-instance","common/models/instances/job-role-instance"],function(){}),define("common/services/dialog/dialog",["common/lodash","common/modules/services"],function(e,t){"use strict";function n(t,n,r){function i(i){var o;if(!e.isObject(i))throw new Error("Dialog Service: Options passed should be an object");return o=n.children(),t.open({appendTo:o.length?o.eq(0):n,size:"sm",controller:"DialogController",template:r.get("dialog.html"),resolve:{options:function(){return i}}}).result}return{open:i}}t.factory("dialog",n),n.$inject=["$uibModal","$rootElement","$templateCache"]}),define("common/controllers/dialog/dialog-ctrl",["common/lodash","common/modules/controllers"],function(e,t){"use strict";function n(t,n,r,i){function o(t){e.assign(n,e.defaultsDeep(t,{title:"CiviHR",msg:"",copyConfirm:"",copyCancel:"",classConfirm:"btn-primary",loading:!1}))}function a(){r.close(!1)}function s(){n.loading=!0,r.closed.then(n.onCloseAfterConfirm),t.resolve().then(n.onConfirm).then(function(){r.close(!0)})}n.cancel=a,n.confirm=s,function(){o(i),i.optionsPromise&&i.optionsPromise().then(function(e){o(e)})}()}t.controller("DialogController",n),n.$inject=["$q","$scope","$uibModalInstance","options"]}),define("common/modules/dialog",["common/angular","common/services/dialog/dialog","common/controllers/dialog/dialog-ctrl","common/angularBootstrap","common/directives/loading","common/modules/templates"],function(e){"use strict";return e.module("common.dialog",["ui.bootstrap","common.directives","common.templates"])}),define("common/decorators/xeditable-civi/editable-directive-factory",[],function(){"use strict";return["$delegate",function(e){return function(t){var n=e(t);return n.compile=function(e){var t,r=e[0].attributes.getNamedItem("ng-href");return e.append(''),r&&(t=angular.element(""),t.text("Follow link"),t.attr(r.nodeName,r.value),t.attr("ng-click","$event.stopPropagation();"),t.addClass("editable-link"),e.append(t),e.addClass("editable-with-link")),{post:n.link}},n}}]}),define("common/directives/xeditable-civi/editable-ta",[],function(){"use strict";return["editableDirectiveFactory","$timeout",function(e,t){var n,r;return r=e({directiveName:"editableTa",inputTpl:"",render:function(){this.parent.render.call(this),this.inputEl.parent().parent().removeClass("form-inline"),this.inputEl.addClass("editable-ta"),this.inputEl.attr("ng-model","ta.$data"),this.inputEl.attr("ta-toolbar",this.attrs.eTaToolbar||'[["bold","italics","underline","strikeThrough","ul","ol","undo","redo","clear"]]'),t(function(){this.inputEl.find("textarea").hide()}.bind(this),0)},save:function(){this.scope.$data=this.scope.ta.$data,this.parent.save.call(this)},setLocalValue:function(){this.parent.setLocalValue.call(this),this.scope.ta.$data=this.scope.$data}}),n=r.link,r.link=function(e,t,r,i){return e.ta={},n(e,t,r,i)},r}]}),define("common/modules/xeditable-civi",["common/angular","common/decorators/xeditable-civi/editable-directive-factory","common/directives/xeditable-civi/editable-ta","common/angularXeditable","common/text-angular"],function(e,t,n){"use strict";return e.module("xeditable-civi",["xeditable","textAngular"]).directive("editableTa",n)}); //# sourceMappingURL=/sites/all/modules/civicrm/tools/extensions/civihr/org.civicrm.reqangular/dist/reqangular.min.js.map \ No newline at end of file diff --git a/org.civicrm.reqangular/info.xml b/org.civicrm.reqangular/info.xml index 12c58d4887d..4cce28c13f0 100755 --- a/org.civicrm.reqangular/info.xml +++ b/org.civicrm.reqangular/info.xml @@ -10,8 +10,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/org.civicrm.reqangular/src/common/bundles/services.js b/org.civicrm.reqangular/src/common/bundles/services.js index 97d9e1484c8..88c762c3e82 100644 --- a/org.civicrm.reqangular/src/common/bundles/services.js +++ b/org.civicrm.reqangular/src/common/bundles/services.js @@ -3,6 +3,7 @@ define([ 'common/services/before-hash-query-params.service', 'common/services/check-permissions', + 'common/services/crm-ang.service', 'common/services/detect-device.service', 'common/services/dom-event-trigger', 'common/services/file-mime-types', diff --git a/org.civicrm.reqangular/src/common/decorators/ui-bootstrap/uib-modal.decorator.js b/org.civicrm.reqangular/src/common/decorators/ui-bootstrap/uib-modal.decorator.js index 62b314f29cd..dd1d7f58af7 100644 --- a/org.civicrm.reqangular/src/common/decorators/ui-bootstrap/uib-modal.decorator.js +++ b/org.civicrm.reqangular/src/common/decorators/ui-bootstrap/uib-modal.decorator.js @@ -19,40 +19,18 @@ define([ */ function open () { var modalInstance; - var elements = [ - { - item: angular.element($document[0].body), - styles: [ - { name: 'overflow', old: null, new: 'hidden' }, - { name: 'height', old: null, new: '100%' }, - { name: 'width', old: null, new: '100%' } - ] - }, - { - item: angular.element($document[0].getElementsByTagName('html')[0]), - styles: [ - { name: 'overflow', old: null, new: 'hidden' }, - { name: 'height', old: null, new: '100%' }, - { name: 'width', old: null, new: '100%' } - ] - } - ]; + var $elements = $document.find('body, html'); - elements.forEach(function (element) { - element.styles.forEach(function (style) { - style.old = element.item.css(style.name); - element.item.css(style.name, style.new); - }); - }); + $elements.addClass('chr_scroll-lock'); modalInstance = originalOpenFunction.apply(this, arguments); modalInstance.closed.then(function () { - elements.forEach(function (element) { - element.styles.forEach(function (style) { - element.item.css(style.name, style.old); - }); - }); + if ($document.find('.modal-dialog').length) { + return; + } + + $elements.removeClass('chr_scroll-lock'); }); return modalInstance; diff --git a/org.civicrm.reqangular/src/common/directives/time-amount-picker.directive.js b/org.civicrm.reqangular/src/common/directives/time-amount-picker.directive.js index 89ca4ccffda..7d009dc419c 100644 --- a/org.civicrm.reqangular/src/common/directives/time-amount-picker.directive.js +++ b/org.civicrm.reqangular/src/common/directives/time-amount-picker.directive.js @@ -38,6 +38,7 @@ define([ (function init () { parseCurrentValue(); + buildOptions(); watchTimeAmountPickerOptions(); })(); @@ -111,6 +112,7 @@ define([ }); $scope.$watch('value', function () { parseCurrentValue(); + buildOptions(); }); $scope.$watchGroup(['minAmount', 'maxAmount', 'interval'], function () { buildOptions(); diff --git a/org.civicrm.reqangular/src/common/models/option-group.js b/org.civicrm.reqangular/src/common/models/option-group.js index 83d98b8912d..ed8cff49783 100644 --- a/org.civicrm.reqangular/src/common/models/option-group.js +++ b/org.civicrm.reqangular/src/common/models/option-group.js @@ -1,28 +1,30 @@ +/* eslint-env amd */ + define([ - 'common/modules/models', - 'common/models/model', - 'common/services/api/option-group' + 'common/modules/models', + 'common/models/model', + 'common/services/api/option-group' ], function (models) { - 'use strict'; - - models.factory('OptionGroup', [ - 'Model', 'api.optionGroup', - function (Model, optionGroupAPI) { + 'use strict'; - return Model.extend({ + models.factory('OptionGroup', [ + 'Model', 'api.optionGroup', + function (Model, optionGroupAPI) { + return Model.extend({ - /** - * Returns the values of a sigle or multiple option groups - * - * @param {string/array} names - * Bases on the type of the parameter, the method will return - * either an array of values (string) or an object (array) - * @return {Promise} - */ - valuesOf: function (names) { - return optionGroupAPI.valuesOf(names); - } - }); + /** + * Returns the values of a sigle or multiple option groups + * + * @param {String|Array} names + * Bases on the type of the parameter, the method will return + * either an array of values (string) or an object (array) + * @param {Boolean} [cache] parameter to cache the query or not + * @return {Promise} + */ + valuesOf: function (names, cache) { + return optionGroupAPI.valuesOf(names, cache); } - ]); + }); + } + ]); }); diff --git a/org.civicrm.reqangular/src/common/services/api.js b/org.civicrm.reqangular/src/common/services/api.js index 063be50366f..e44d6abc39e 100644 --- a/org.civicrm.reqangular/src/common/services/api.js +++ b/org.civicrm.reqangular/src/common/services/api.js @@ -7,7 +7,7 @@ define([ ], function (angular, _, apis) { 'use strict'; - apis.factory('api', ['$log', '$http', '$httpParamSerializer', '$q', '$timeout', function ($log, $http, $httpParamSerializer, $q, $timeout) { + apis.factory('api', ['$cacheFactory', '$log', '$http', '$httpParamSerializer', '$q', '$timeout', function ($cacheFactory, $log, $http, $httpParamSerializer, $q, $timeout) { $log.debug('api'); var API_ENDPOINT = '/civicrm/ajax/rest'; @@ -140,24 +140,33 @@ define([ /** * Sends a GET request to the backend endpoint * - * @param {string} entity - The entity the request is asking for (Contact, Appraisal, etc) - * @param {string} action - The action to perform - * @param {object} params - Any additional parameters to pass in the request - * @param {boolean} cache - If the response should be cached (default = true) + * @param {String} entity - The entity the request is asking for (Contact, Appraisal, etc) + * @param {String} action - The action to perform + * @param {Object} params - Any additional parameters to pass in the request + * @param {Boolean} returnCachedData + * - if passed as `true` or not passed, returns data from cache (if not the first call) + * - if passed as `false`, returns updated data from API and caches for future requests * @return {Promise} */ - sendGET: function (entity, action, params, cache) { + sendGET: function (entity, action, params, returnCachedData) { + var queryJSON = { + action: action, + entity: entity, + json: prepareParams(params), + sequential: 1 + }; + + if (returnCachedData === false) { + $cacheFactory.get('$http').remove( + API_ENDPOINT + '?' + $httpParamSerializer(queryJSON)); + } + return $http({ method: 'GET', url: API_ENDPOINT, - cache: (typeof cache !== 'undefined' ? !!cache : true), + cache: true, responseType: 'json', - params: { - sequential: 1, - json: prepareParams(params), - entity: entity, - action: action - } + params: queryJSON }).then(responseHandler); }, diff --git a/org.civicrm.reqangular/src/common/services/api/option-group.js b/org.civicrm.reqangular/src/common/services/api/option-group.js index ad95ed1f184..b6d6b9b2a88 100644 --- a/org.civicrm.reqangular/src/common/services/api/option-group.js +++ b/org.civicrm.reqangular/src/common/services/api/option-group.js @@ -52,30 +52,30 @@ define([ /** * Returns the values of the option groups with the given names * - * @param {string/array} groupNames + * @param {String|Array} groupNames * If the value is an array of names, the method will group * the values by option group names - * @param {object} params optional parameters for the query + * @param {Boolean} cache optional parameter to cache the query or not * @return {Promise} * Resolves to an array with the values (if `groupNames` is a string) * or an object with keys as the group names and values as the * array of their option values (if `groupNames` is an array) */ - valuesOf: function (groupNames, params) { + valuesOf: function (groupNames, cache) { var multiple = _.isArray(groupNames); - return this.sendGET('OptionValue', 'get', _.assign({ + return this.sendGET('OptionValue', 'get', { 'option_group_id.name': { 'IN': multiple ? groupNames : [groupNames] }, 'is_active': '1', 'return': [ 'option_group_id.name', 'option_group_id', 'id', 'name', 'label', 'value', 'weight', 'is_active', 'is_reserved' ] - }, params)) - .then(normalizeResponse) - .then(function (optionValues) { - return multiple ? valuesByGroup(optionValues) : optionValues; - }); + }, cache) + .then(normalizeResponse) + .then(function (optionValues) { + return multiple ? valuesByGroup(optionValues) : optionValues; + }); } }); }]); diff --git a/org.civicrm.reqangular/src/common/services/crm-ang.service.js b/org.civicrm.reqangular/src/common/services/crm-ang.service.js new file mode 100644 index 00000000000..1d16f360ea4 --- /dev/null +++ b/org.civicrm.reqangular/src/common/services/crm-ang.service.js @@ -0,0 +1,29 @@ +/* eslint-env amd */ + +(function (CRM) { + define([ + 'common/lodash', + 'common/modules/services' + ], function (_, services) { + 'use strict'; + + services.factory('crmAngService', function () { + return { + loadForm: loadForm + }; + }); + + /** + * Opens a CRM form with a provided url and options + * This is simply a wrapper to CRM.loadForm + * @see https://docs.civicrm.org/dev/en/latest/framework/ajax + * + * @param {String} url + * @param {Object} options + * @return {Object} extended jQuery object + */ + function loadForm (url, options) { + return CRM.loadForm(url, options); + } + }); +}(CRM)); diff --git a/org.civicrm.reqangular/test/decorators/ui-bootstrap/uib-modal.decorator.spec.js b/org.civicrm.reqangular/test/decorators/ui-bootstrap/uib-modal.decorator.spec.js index b5fc40dba3b..0fb2a59524a 100644 --- a/org.civicrm.reqangular/test/decorators/ui-bootstrap/uib-modal.decorator.spec.js +++ b/org.civicrm.reqangular/test/decorators/ui-bootstrap/uib-modal.decorator.spec.js @@ -10,7 +10,7 @@ define([ 'use strict'; describe('$uibModal.open', function () { - var $uibModal, $document; + var $document, $rootScope, $uibModal; beforeEach(module('ui.bootstrap')); @@ -18,56 +18,86 @@ define([ $provide.decorator('$uibModal', $uibModalDecorator); })); - beforeEach(inject(function (_$document_, _$uibModal_) { + beforeEach(inject(function (_$document_, _$rootScope_, _$uibModal_) { $document = _$document_; + $rootScope = _$rootScope_; $uibModal = _$uibModal_; })); describe('init', function () { - var originalStyles; + var $elements; var arg1 = { template: '' }; var arg2 = 'another_argument'; - var elements = {}; beforeEach(function () { - elements.body = $document[0].body; - elements.html = $document[0].getElementsByTagName('html')[0]; - - if (!originalStyles) { - originalStyles = { - body: _.clone(elements.body.style), - html: _.clone(elements.html.style) - }; - } + $elements = $document.find('body, html'); }); describe('when modal is opened', function () { - var modalInstance; + var modalInstance1; beforeEach(function () { - modalInstance = $uibModal.open(arg1, arg2); + modalInstance1 = $uibModal.open(arg1, arg2); + $rootScope.$digest(); }); - ['body', 'html'].forEach(function (element) { - _.forOwn({ overflow: 'hidden', height: '100%', width: '100%' }, function (value, style) { - it('sets ' + style + ' to ' + value + ' for <' + element + '>', function () { - expect(elements[element].style[style]).toBe(value); - }); - }); + afterEach(function () { + $document.find('.modal-dialog').remove(); + }); + + it('locks document scroll', function () { + expect($document.find('.modal-dialog').length).toBe(1); + expect($elements.hasClass('chr_scroll-lock')).toBe(true); }); describe('when modal is closed', function () { beforeEach(function () { - // @TODO The solution to simply close the modal was not found and - // the test cannot be run at the moment. If you have any idea - // on how to make this test work, please amend it and turn on. - modalInstance.close(); + // Closes the modal and executes the listener + $document.find('.modal-dialog').remove(); + modalInstance1.closed.$$state.pending[0][1](); + }); + + it('unlocks document scroll', function () { + expect($document.find('.modal-dialog').length).toBe(0); + expect($elements.hasClass('chr_scroll-lock')).toBe(false); }); + }); + + describe('when second modal is opened on top of the first modal', function () { + var modalInstance2; + + beforeEach(function () { + modalInstance2 = $uibModal.open(arg1, arg2); + $rootScope.$digest(); + }); + + it('remains document scroll locked', function () { + expect($document.find('.modal-dialog').length).toBe(2); + expect($elements.hasClass('chr_scroll-lock')).toBe(true); + }); + + describe('when second modal is closed', function () { + beforeEach(function () { + // Closes second modal and executes the listener + $document.find('.modal-dialog').last().remove(); + modalInstance2.closed.$$state.pending[0][1](); + }); + + it('remains document scroll locked', function () { + expect($document.find('.modal-dialog').length).toBe(1); + expect($elements.hasClass('chr_scroll-lock')).toBe(true); + }); + + describe('and when the first modal is closed', function () { + beforeEach(function () { + // Closes the first modal and executes the listener + $document.find('.modal-dialog').first().remove(); + modalInstance1.closed.$$state.pending[0][1](); + }); - ['body', 'html'].forEach(function (element) { - ['width', 'height', 'overflow'].forEach(function (style) { - xit('sets original ' + style + ' for <' + element + '>', function () { - expect(elements[element].style[style]).toBe(originalStyles[element][style]); + it('unlocks document scroll', function () { + expect($document.find('.modal-dialog').length).toBe(0); + expect($elements.hasClass('chr_scroll-lock')).toBe(false); }); }); }); diff --git a/org.civicrm.reqangular/test/directives/time-amount-picker.directive.spec.js b/org.civicrm.reqangular/test/directives/time-amount-picker.directive.spec.js index 5fe95f43066..9d53db1a659 100644 --- a/org.civicrm.reqangular/test/directives/time-amount-picker.directive.spec.js +++ b/org.civicrm.reqangular/test/directives/time-amount-picker.directive.spec.js @@ -9,7 +9,7 @@ define([ 'use strict'; describe('timeAmountPicker directive', function () { - var vm, $compile, $scope, $rootScope; + var element, vm, $compile, $scope, $rootScope; beforeEach(module('common.directives')); beforeEach(inject(function (_$rootScope_, _$compile_) { @@ -56,6 +56,7 @@ define([ describe('when hours value is changed and it is less than the minimum specified', function () { beforeEach(function () { vm.selectedHours = 2; + vm.buildMinutesOptions(); }); @@ -89,6 +90,7 @@ define([ describe('when hours value is changed and it is same as the maximum specified', function () { beforeEach(function () { vm.selectedHours = 7; + vm.buildMinutesOptions(); }); @@ -111,12 +113,13 @@ define([ }); }); - describe('when "time-amount-picker-value" attribute is passed', function () { + describe('when "time-amount-picker-value" attribute is passed along with maximum amount', function () { var valueObject = { value: '6.5' }; beforeEach(function () { buildDirective([ - { key: 'time-amount-picker-value', value: valueObject.value, bind: '=' } + { key: 'time-amount-picker-value', value: valueObject.value, bind: '=' }, + { key: 'time-amount-picker-max-amount', value: valueObject.value, bind: '>' } ]); }); @@ -128,6 +131,10 @@ define([ expect(vm.selectedMinutes).toBe('30'); }); + it('sets value', function () { + expect(element.isolateScope().value).toBe(6.5); + }); + describe('when selected values are changed', function () { beforeEach(function () { vm.selectedHours = 8; @@ -137,7 +144,29 @@ define([ }); it('sets the result value back', function () { - expect($scope.$$childTail.value).toBe(8.75); + expect(element.isolateScope().value).toBe(8.75); + }); + }); + + describe('when maximum amount is set to greater hours amount but less minutes amount', function () { + var newValue = '7'; + + beforeEach(function () { + element.isolateScope().maxAmount = newValue; + + $scope.$digest(); + }); + + describe('when the maximum possible value is set', function () { + beforeEach(function () { + element.isolateScope().value = newValue; + + $scope.$digest(); + }); + + it('builds correct minutes options', function () { + expect(vm.minutesOptions).toEqual([0]); + }); }); }); }); @@ -163,8 +192,8 @@ define([ */ function buildDirective (options) { var attrWrapper = ''; - var element = angular.element(''); + element = angular.element(''); $scope = $rootScope.$new(); options = options || []; diff --git a/org.civicrm.reqangular/test/models/option-group.spec.js b/org.civicrm.reqangular/test/models/option-group.spec.js index 25ec5133891..d96201ab043 100644 --- a/org.civicrm.reqangular/test/models/option-group.spec.js +++ b/org.civicrm.reqangular/test/models/option-group.spec.js @@ -14,7 +14,7 @@ define([ module('common.models', 'common.mocks', function (_$provide_) { $provide = _$provide_; }); - // Override api.optionGroup with the mocked version + // Override api.optionGroup with the mocked version inject(['api.optionGroup.mock', function (_optionGroupAPIMock_) { $provide.value('api.optionGroup', _optionGroupAPIMock_); }]); @@ -35,12 +35,44 @@ define([ }); describe('valuesOf()', function () { - beforeEach(function () { - OptionGroup.valuesOf('hrjc_department'); + var optionGroupName = 'hrjc_department'; + + describe('when just a single option group name is passed', function () { + beforeEach(function () { + OptionGroup.valuesOf(optionGroupName); + }); + + it('calls the correct API method', function () { + expect(optionGroupAPI.valuesOf.calls.mostRecent().args[0]).toBe(optionGroupName); + }); + + it('caches requests by default', function () { + expect(optionGroupAPI.valuesOf.calls.mostRecent().args[1]).toBe(undefined); + }); }); - it('calls the correct API method', function () { - expect(optionGroupAPI.valuesOf).toHaveBeenCalled(); + describe('when several option group names are passed', function () { + var multipleOptionGroupNames = [optionGroupName, 'some_other_option']; + + beforeEach(function () { + OptionGroup.valuesOf(multipleOptionGroupNames); + }); + + it('passes the array of option group names to the API method', function () { + expect(optionGroupAPI.valuesOf.calls.mostRecent().args[0]).toBe(multipleOptionGroupNames); + }); + }); + + describe('when caching is disabled', function () { + var cache = false; + + beforeEach(function () { + OptionGroup.valuesOf(optionGroupName, cache); + }); + + it('does not cache requests', function () { + expect(optionGroupAPI.valuesOf.calls.mostRecent().args[1]).toBe(cache); + }); }); }); }); diff --git a/org.civicrm.reqangular/test/services/api.spec.js b/org.civicrm.reqangular/test/services/api.spec.js index 2dae65bbd24..0ab7210c85f 100644 --- a/org.civicrm.reqangular/test/services/api.spec.js +++ b/org.civicrm.reqangular/test/services/api.spec.js @@ -8,23 +8,22 @@ define([ 'use strict'; describe('api', function () { - var api, $httpBackend, $httpParamSerializer, $rootScope; + var api, $cacheFactory, $httpBackend, $httpParamSerializer, $rootScope; var entity = 'entity'; var action = 'action'; beforeEach(module('common.apis')); - beforeEach(inject(function (_api_, _$httpBackend_, _$httpParamSerializer_, _$rootScope_) { + beforeEach(inject(function (_api_, _$cacheFactory_, _$httpBackend_, _$httpParamSerializer_, _$rootScope_) { api = _api_; + $cacheFactory = _$cacheFactory_; $httpBackend = _$httpBackend_; $httpParamSerializer = _$httpParamSerializer_; $rootScope = _$rootScope_; })); - describe('sendGET', function () { - var promise; - - afterEach(function () { $httpBackend.flush(); }); + describe('sendGET()', function () { + var expectedResponse; describe('when the API does not return an error', function () { var returnValue = { @@ -33,13 +32,15 @@ define([ }; beforeEach(function () { - promise = expectAndSendGET(returnValue); + expectAndSendGET(returnValue) + .then(function (response) { + expectedResponse = response; + }); + $httpBackend.flush(); }); it('returns values sent from API', function () { - promise.then(function (response) { - expect(response).toEqual(returnValue); - }); + expect(expectedResponse).toEqual(returnValue); }); }); @@ -50,13 +51,15 @@ define([ }; beforeEach(function () { - promise = expectAndSendGET(returnValue); + expectAndSendGET(returnValue) + .catch(function (response) { + expectedResponse = response; + }); + $httpBackend.flush(); }); it('rejects the promise with the error message provided by the API', function () { - promise.catch(function (response) { - expect(response).toBe(returnValue.error_message); - }); + expect(expectedResponse).toBe(returnValue.error_message); }); }); @@ -66,20 +69,20 @@ define([ somekey: 'someval' }; + beforeEach(function () { + spyOn(api, 'sendGET').and.callThrough(); + }); + describe('when limit is sent as a parameter', function () { var limit = 5; beforeEach(function () { - expectAndSendGET(returnValue, {options: {limit: limit}}); + expectAndSendGET(returnValue, { options: { limit: limit } }); + $httpBackend.flush(); }); - it('send a GET request with original limit value', function () { - $httpBackend.expectGET('/civicrm/ajax/rest?' + $httpParamSerializer({ - json: {options: {limit: limit}}, - sequential: 1, - action: action, - entity: entity - })); + it('sends a GET request with original limit value', function () { + expect(api.sendGET.calls.mostRecent().args[2]).toEqual({ options: { limit: limit } }); }); }); @@ -88,13 +91,80 @@ define([ expectAndSendGET(returnValue); }); - it('send a GET request with 0 set as limit', function () { - $httpBackend.expectGET('/civicrm/ajax/rest?' + $httpParamSerializer({ - json: {options: {limit: 0}}, - sequential: 1, + it('sends a GET request with 0 set as limit', function () { + expect(api.sendGET.calls.mostRecent().args[2]).not.toBeDefined(); + }); + }); + }); + + describe('caching', function () { + var cacheSize; + var sampleResult = 'sample result'; + var sampleParams = {}; + + beforeEach(function () { + spyOn($cacheFactory.get('$http'), 'remove').and.callThrough(); + }); + + describe('when "returnCachedData" parameter is not passed', function () { + beforeEach(function () { + expectAndSendGET(sampleResult, sampleParams); + $rootScope.$digest(); + + cacheSize = $cacheFactory.get('$http').info().size; + }); + + it('does not flush cache before HTTP call', function () { + expect($cacheFactory.get('$http').remove).not.toHaveBeenCalled(); + }); + + it('caches data by default', function () { + expect(cacheSize).toBe(1); + }); + }); + + describe('when "returnCachedData" parameter passed as `true`', function () { + beforeEach(function () { + expectAndSendGET(sampleResult, sampleParams, true); + $rootScope.$digest(); + + cacheSize = $cacheFactory.get('$http').info().size; + }); + + it('does not flush cache before HTTP call', function () { + expect($cacheFactory.get('$http').remove).not.toHaveBeenCalled(); + }); + + it('caches data', function () { + expect(cacheSize).toBe(1); + }); + }); + + describe('when "returnCachedData" parameter passed as `false`', function () { + var cacheResultKey; + + beforeEach(function () { + // An URL that is constructed during calling $http method + // is used by $cacheFactory to keep the cached results + cacheResultKey = '/civicrm/ajax/rest?' + $httpParamSerializer({ action: action, - entity: entity - })); + entity: entity, + json: { options: { limit: 0 } }, + sequential: 1 + }); + + expectAndSendGET(sampleResult, sampleParams, false); + $rootScope.$digest(); + + cacheSize = $cacheFactory.get('$http').info().size; + }); + + it('flushes cache before HTTP call', function () { + expect($cacheFactory.get('$http').remove).toHaveBeenCalledWith(cacheResultKey); + }); + + it('caches updated data for future requests', function () { + expect(cacheSize).toBe(1); }); }); }); @@ -104,21 +174,20 @@ define([ * * @param {any} returnValue - value to be returned by the GET request * @param {Object} params - params to be used in the API call + * @param {Boolean} cache * @return {Promise} */ - function expectAndSendGET (returnValue, params) { + function expectAndSendGET (returnValue, params, cache) { $httpBackend .whenGET(new RegExp('action=' + action + '&entity=' + entity)) .respond(returnValue); - return api.sendGET(entity, action, params, true); + return api.sendGET(entity, action, params, cache); } }); - describe('sendPOST', function () { - var promise; - - afterEach(function () { $httpBackend.flush(); }); + describe('sendPOST()', function () { + var expectedResponse; describe('when the API doesnt return an error', function () { var returnValue = { @@ -127,13 +196,15 @@ define([ }; beforeEach(function () { - promise = expectAndSendPOST(returnValue); + expectAndSendPOST(returnValue) + .then(function (response) { + expectedResponse = response; + }); + $httpBackend.flush(); }); it('returns values sent from API', function () { - promise.then(function (response) { - expect(response).toEqual(returnValue); - }); + expect(expectedResponse).toEqual(returnValue); }); }); @@ -144,13 +215,15 @@ define([ }; beforeEach(function () { - promise = expectAndSendPOST(returnValue); + expectAndSendPOST(returnValue) + .catch(function (response) { + expectedResponse = response; + }); + $httpBackend.flush(); }); it('rejects the promise with the error message provided by the API', function () { - promise.catch(function (response) { - expect(response).toBe(returnValue.error_message); - }); + expect(expectedResponse).toBe(returnValue.error_message); }); }); @@ -160,20 +233,19 @@ define([ somekey: 'someval' }; + beforeEach(function () { + spyOn(api, 'sendPOST').and.callThrough(); + }); + describe('when limit is sent as a parameter', function () { var limit = 5; beforeEach(function () { - expectAndSendPOST(returnValue, {options: {limit: limit}}); + expectAndSendPOST(returnValue, { options: { limit: limit } }); }); it('send a POST request with original limit value', function () { - $httpBackend.expectPOST('/civicrm/ajax/rest', $httpParamSerializer({ - json: { options: { limit: limit } }, - sequential: 1, - action: action, - entity: entity - })); + expect(api.sendPOST.calls.mostRecent().args[2]).toEqual({ options: { limit: limit } }); }); }); @@ -183,12 +255,7 @@ define([ }); it('send a POST request with 0 set as limit', function () { - $httpBackend.expectPOST('/civicrm/ajax/rest', $httpParamSerializer({ - json: { options: { limit: 0 } }, - sequential: 1, - action: action, - entity: entity - })); + expect(api.sendPOST.calls.mostRecent().args[2]).not.toBeDefined(); }); }); }); diff --git a/org.civicrm.reqangular/test/services/api/contact_test.js b/org.civicrm.reqangular/test/services/api/contact.spec.js similarity index 66% rename from org.civicrm.reqangular/test/services/api/contact_test.js rename to org.civicrm.reqangular/test/services/api/contact.spec.js index ac75bdc08e3..7f9d1a2b062 100644 --- a/org.civicrm.reqangular/test/services/api/contact_test.js +++ b/org.civicrm.reqangular/test/services/api/contact.spec.js @@ -1,15 +1,15 @@ +/* eslint-env amd, jasmine */ + define([ + 'common/lodash', 'common/angularMocks', 'common/services/api/contact', 'common/mocks/services/api/contact-mock' -], function () { +], function (_) { 'use strict'; - describe("api.contact", function () { - var ContactAPI, - $rootScope, - ContactAPIMock, - $q; + describe('api.contact', function () { + var ContactAPI, $rootScope, ContactAPIMock, $q; beforeEach(module('common.apis', 'common.mocks')); @@ -20,18 +20,18 @@ define([ $q = _$q_; }])); - it("has expected interface", function () { - expect(Object.keys(ContactAPI)).toContain("all"); - expect(Object.keys(ContactAPI)).toContain("find"); - expect(Object.keys(ContactAPI)).toContain("leaveManagees"); + it('has expected interface', function () { + expect(Object.keys(ContactAPI)).toContain('all'); + expect(Object.keys(ContactAPI)).toContain('find'); + expect(Object.keys(ContactAPI)).toContain('leaveManagees'); }); - describe("all()", function () { - var contactApiPromise, - filters = {key: "filters"}, - pagination = {key: "pagination"}, - sort = "sort", - additionalParams = {key: "additionalParams"}; + describe('all()', function () { + var contactApiPromise; + var filters = { key: 'filters' }; + var pagination = { key: 'pagination' }; + var sort = 'sort'; + var additionalParams = { key: 'additionalParams' }; beforeEach(function () { spyOn(ContactAPI, 'getAll').and.returnValue($q.resolve(ContactAPIMock.mockedContacts())); @@ -42,21 +42,20 @@ define([ $rootScope.$apply(); }); - it("returns all the contact", function () { + it('returns all the contact', function () { contactApiPromise.then(function (result) { expect(result).toEqual(ContactAPIMock.mockedContacts()); }); }); - it("calls getAll method", function () { + it('calls getAll method', function () { expect(ContactAPI.getAll).toHaveBeenCalledWith('Contact', filters, pagination, sort, additionalParams); }); }); - describe("find()", function () { - var contactApiPromise, - contactId = '2', - contact; + describe('find()', function () { + var contactApiPromise, contact; + var contactId = '2'; beforeEach(function () { contact = ContactAPIMock.mockedContacts().list[0]; @@ -70,23 +69,23 @@ define([ $rootScope.$apply(); }); - it("returns a contact", function () { + it('returns a contact', function () { contactApiPromise.then(function (result) { expect(result).toEqual(contact); }); }); - it("calls sendGET method", function () { + it('calls sendGET method', function () { expect(ContactAPI.sendGET).toHaveBeenCalledWith('Contact', 'get', {id: '' + contactId}, false); }); }); - describe("leaveManagees()", function () { - var contactApiPromise, - managedBy = '101', - params = { - key: 'value' - }; + describe('leaveManagees()', function () { + var contactApiPromise; + var managedBy = '101'; + var params = { + key: 'value' + }; beforeEach(function () { spyOn(ContactAPI, 'sendGET').and.returnValue($q.resolve({ @@ -99,13 +98,13 @@ define([ $rootScope.$apply(); }); - it("returns the contacts", function () { + it('returns the contacts', function () { contactApiPromise.then(function (result) { expect(result).toEqual(ContactAPIMock.mockedContacts().list); }); }); - it("calls sendGET method", function () { + it('calls sendGET method', function () { expect(ContactAPI.sendGET).toHaveBeenCalledWith('Contact', 'getleavemanagees', _.assign(params, { managed_by: managedBy })); diff --git a/org.civicrm.reqangular/test/services/api/job-role_test.js b/org.civicrm.reqangular/test/services/api/job-role.spec.js similarity index 67% rename from org.civicrm.reqangular/test/services/api/job-role_test.js rename to org.civicrm.reqangular/test/services/api/job-role.spec.js index 19a56842676..0e639e3617f 100644 --- a/org.civicrm.reqangular/test/services/api/job-role_test.js +++ b/org.civicrm.reqangular/test/services/api/job-role.spec.js @@ -1,3 +1,5 @@ +/* eslint-env amd, jasmine */ + define([ 'common/angularMocks', 'common/services/api/job-role', @@ -5,11 +7,8 @@ define([ ], function () { 'use strict'; - describe("api.job-role", function () { - var JobRoleAPI, - $rootScope, - JobRoleAPIMock, - $q; + describe('api.job-role', function () { + var JobRoleAPI, $rootScope, JobRoleAPIMock, $q; beforeEach(module('common.apis', 'common.mocks')); @@ -20,17 +19,17 @@ define([ $q = _$q_; }])); - it("has expected interface", function () { - expect(Object.keys(JobRoleAPI)).toContain("all"); - expect(Object.keys(JobRoleAPI)).toContain("find"); + it('has expected interface', function () { + expect(Object.keys(JobRoleAPI)).toContain('all'); + expect(Object.keys(JobRoleAPI)).toContain('find'); }); - describe("all()", function () { - var jobRoleApiPromise, - filters = {key: "filters"}, - pagination = {key: "pagination"}, - sort = "sort", - additionalParams = {key: "additionalParams"}; + describe('all()', function () { + var jobRoleApiPromise; + var filters = { key: 'filters' }; + var pagination = { key: 'pagination' }; + var sort = 'sort'; + var additionalParams = { key: 'additionalParams' }; beforeEach(function () { spyOn(JobRoleAPI, 'getAll').and.returnValue($q.resolve(JobRoleAPIMock.mockedJobRoles)); @@ -41,20 +40,20 @@ define([ $rootScope.$apply(); }); - it("returns all the job roles", function () { + it('returns all the job roles', function () { jobRoleApiPromise.then(function (result) { expect(result).toEqual(JobRoleAPIMock.mockedJobRoles); }); }); - it("calls getAll method", function () { + it('calls getAll method', function () { expect(JobRoleAPI.getAll).toHaveBeenCalledWith('HrJobRoles', filters, pagination, sort, additionalParams); }); }); - describe("find()", function () { - var jobRoleApiPromise, - jobRoleID = '2'; + describe('find()', function () { + var jobRoleApiPromise; + var jobRoleID = '2'; beforeEach(function () { spyOn(JobRoleAPI, 'sendGET').and.returnValue($q.resolve({ @@ -67,13 +66,13 @@ define([ $rootScope.$apply(); }); - it("returns a job role", function () { + it('returns a job role', function () { jobRoleApiPromise.then(function (result) { expect(result).toEqual(JobRoleAPIMock.mockedJobRoles.list[0]); }); }); - it("calls sendGET method", function () { + it('calls sendGET method', function () { expect(JobRoleAPI.sendGET).toHaveBeenCalledWith('HRJobRole', 'get', {id: '' + jobRoleID}, false); }); }); diff --git a/org.civicrm.reqangular/test/services/api/option-group.spec.js b/org.civicrm.reqangular/test/services/api/option-group.spec.js new file mode 100644 index 00000000000..d1a96a97660 --- /dev/null +++ b/org.civicrm.reqangular/test/services/api/option-group.spec.js @@ -0,0 +1,92 @@ +/* eslint-env amd, jasmine */ + +define([ + 'common/angularMocks', + 'common/models/option-group', + 'common/mocks/services/api/option-group-mock' +], function () { + 'use strict'; + + describe('api.option-group', function () { + var $q, OptionGroupAPI; + + beforeEach(module('common.models', 'common.mocks')); + + beforeEach(inject([ + 'api.optionGroup', + function (_optionGroupAPI_) { + OptionGroupAPI = _optionGroupAPI_; + } + ])); + + beforeEach(inject(function (_$q_) { + $q = _$q_; + })); + + it('has the expected api', function () { + expect(Object.keys(OptionGroupAPI)).toEqual(['valuesOf']); + }); + + describe('valuesOf()', function () { + var optionGroupName = 'hrjc_department'; + + beforeEach(function () { + spyOn(OptionGroupAPI, 'sendGET').and.returnValue($q.resolve()); + }); + + describe('when a single option name is passed', function () { + var sendGETCallArgs; + + beforeEach(function () { + OptionGroupAPI.valuesOf(optionGroupName); + + sendGETCallArgs = OptionGroupAPI.sendGET.calls.mostRecent().args; + }); + + it('calls sendGET with correct API entity and method', function () { + expect(sendGETCallArgs[0]).toBe('OptionValue'); + expect(sendGETCallArgs[1]).toBe('get'); + }); + + it('calls sendGET with correct parameters', function () { + expect(sendGETCallArgs[2]).toEqual({ + 'option_group_id.name': { IN: [ optionGroupName ] }, + is_active: '1', + return: [ 'option_group_id.name', 'option_group_id', 'id', 'name', + 'label', 'value', 'weight', 'is_active', 'is_reserved'] + }); + }); + + it('does not tell sendGET to disable caching the API results', function () { + expect(OptionGroupAPI.sendGET.calls.mostRecent().args[3]).not.toBe(false); + }); + }); + + describe('when multiple option names are passed', function () { + var anotherOptionGroupName = 'hrjc_level_type'; + + beforeEach(function () { + OptionGroupAPI.valuesOf([optionGroupName, anotherOptionGroupName]); + }); + + it('tells backend API to fetch multiple options', function () { + expect(OptionGroupAPI.sendGET.calls.mostRecent().args[2]['option_group_id.name']).toEqual( + { IN: [optionGroupName, anotherOptionGroupName] } + ); + }); + }); + + describe('when no caching is needed', function () { + var cache = false; + + beforeEach(function () { + OptionGroupAPI.valuesOf(optionGroupName, cache); + }); + + it('tells sendGET to not cache the API call', function () { + expect(OptionGroupAPI.sendGET.calls.mostRecent().args[3]).toBe(cache); + }); + }); + }); + }); +}); diff --git a/org.civicrm.reqangular/test/services/crm-ang.service.spec.js b/org.civicrm.reqangular/test/services/crm-ang.service.spec.js new file mode 100644 index 00000000000..d8c893a7e69 --- /dev/null +++ b/org.civicrm.reqangular/test/services/crm-ang.service.spec.js @@ -0,0 +1,40 @@ +/* eslint-env amd, jasmine */ + +(function (CRM) { + define([ + 'common/angular', + 'common/angularMocks', + 'common/services/crm-ang.service' + ], function () { + 'use strict'; + + describe('crmAngService', function () { + var crmAngService; + + beforeEach(module('common.services')); + beforeEach(inject(function (_crmAngService_) { + crmAngService = _crmAngService_; + })); + + describe('loadForm()', function () { + var result; + var url = '/some-url'; + var options = { optionKey: 'optionValue' }; + var originalResult = 'jQuery object'; + + beforeEach(function () { + CRM.loadForm = jasmine.createSpy().and.returnValue(originalResult); + result = crmAngService.loadForm(url, options); + }); + + it('calls CRM.loadForm with according parameters', function () { + expect(CRM.loadForm).toHaveBeenCalledWith(url, options); + }); + + it('returns the same as the original method', function () { + expect(result).toBe(originalResult); + }); + }); + }); + }); +})(CRM); diff --git a/package-lock.json b/package-lock.json index ee4ea49d814..d848417e174 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3826,9 +3826,9 @@ } }, "stylelint-scss": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-2.3.0.tgz", - "integrity": "sha512-gYLw1jma/BUZ9eQ3hsrL/7bddQN2BJ13oSp0A0kOqje4hBrSCrUjf7rmpnK8taRWoU3KASwMo4apWg+YopDK5Q==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-2.5.0.tgz", + "integrity": "sha512-+joZpza5nQxAyGwzRMancFEl0EH9+1Vy88YzBghRMS0wHulzDPE9fEkBi6ZOlz+I3tYIBI4x9NbqO5/LkbeE3Q==", "dev": true, "requires": { "lodash": "4.17.5", diff --git a/package.json b/package.json index 4cd7dcc87f4..364c68001ea 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "postinstall": "npm run sub-install", "sub-install": "for file in `npm run folders-with-dependencies --silent`; do cd `dirname $file`; npm i; cd $OLDPWD >> /dev/null; done", "clean-dependencies": "rm -rf node_modules/; for file in `npm run folders-with-dependencies --silent`; do cd `dirname $file`; rm -rf node_modules/; cd $OLDPWD >> /dev/null; done", - "folders-with-dependencies": "find ./* -type f -mindepth 1 -name package.json | grep -v 'node_modules\\|bower_components'" + "folders-with-dependencies": "find ./* -mindepth 1 -name package.json -type f | grep -v 'node_modules\\|bower_components'" }, "lint-staged": { "*.js": [ @@ -45,7 +45,8 @@ "selector-class-pattern": null, "max-nesting-depth": 3, "no-extra-semicolons": true, - "no-duplicate-selectors": true + "no-duplicate-selectors": true, + "scss/dollar-variable-colon-space-after": "at-least-one-space" } }, "devDependencies": { @@ -55,6 +56,6 @@ "stylelint": "^8.4.0", "stylelint-config-sass-guidelines": "^4.1.0", "stylelint-order": "^0.8.0", - "stylelint-scss": "^2.3.0" + "stylelint-scss": "^2.5.0" } } diff --git a/uk.co.compucorp.civicrm.hrcomments/info.xml b/uk.co.compucorp.civicrm.hrcomments/info.xml index fec9297662c..021e55fc0f6 100644 --- a/uk.co.compucorp.civicrm.hrcomments/info.xml +++ b/uk.co.compucorp.civicrm.hrcomments/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.2 diff --git a/uk.co.compucorp.civicrm.hrcontactactionsmenu/info.xml b/uk.co.compucorp.civicrm.hrcontactactionsmenu/info.xml index 241605144c9..e14a6151ad2 100644 --- a/uk.co.compucorp.civicrm.hrcontactactionsmenu/info.xml +++ b/uk.co.compucorp.civicrm.hrcontactactionsmenu/info.xml @@ -9,8 +9,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/CMSData/Role/DrupalRoleService.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/CMSData/Role/DrupalRoleService.php index 398428fa1ef..614da90a456 100644 --- a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/CMSData/Role/DrupalRoleService.php +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/CMSData/Role/DrupalRoleService.php @@ -5,7 +5,7 @@ /** * Implementation of RoleServiceInterface to interact with a Drupal 7 system */ -class CRM_HRCore_CMSData_Role_DrupalRoleService implements RoleServiceInterface{ +class CRM_HRCore_CMSData_Role_DrupalRoleService implements RoleServiceInterface { /** * @inheritdoc @@ -26,13 +26,13 @@ public function getLatestLoginByRole() { $result = $query->execute()->fetchAllKeyed(); - $roleNames = $this->getRoleNames(); + $roleNames = $this->getRoleMachineNames(); $rolesToExclude = ['authenticated user', 'anonymous user']; $roleNames = array_diff($roleNames, $rolesToExclude); $returnArray = array_fill_keys($roleNames, NULL); foreach ($result as $rid => $loginTimestamp) { - if (array_key_exists($rid, $roleNames)) { + if (isset($roleNames[$rid])) { $roleName = $roleNames[$rid]; $loginDate = NULL; if ($loginTimestamp != 0) { @@ -62,4 +62,25 @@ public function getRoleIds($roles) { return $roleIds; } + /** + * Gets the machine names for roles that have them. Roles without machine + * names, such as 'anonymous user' will default to the role name + * + * @return array + * The array will be in the format 'rid' => 'machine_name' + */ + private function getRoleMachineNames() { + $result = db_select('role', 'r') + ->fields('r', ['rid', 'name', 'machine_name']) + ->execute() + ->fetchAllAssoc('rid', PDO::FETCH_BOTH); + + // use name if machine_name is not set + array_walk($result, function (&$role) { + $role['machine_name'] = $role['machine_name'] ?: $role['name']; + }); + + return array_column($result, 'machine_name', 'rid'); + } + } diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Helper/NavigationMenuHelper.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Helper/NavigationMenuHelper.php new file mode 100644 index 00000000000..5298aa3ddd7 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Helper/NavigationMenuHelper.php @@ -0,0 +1,325 @@ + 'New Item'] + */ + public static function insert(&$menu, $path, $attributes = []) { + $name = self::getItemNameFromPath($path); + $defaults = ['name' => $name, 'label' => $name, 'active' => 1]; + $newItem = ['attributes' => array_merge($defaults, $attributes)]; + + if (self::isRootItem($path)) { + $menu[] = $newItem; + } else { + $parentPath = self::getParentPathFromPath($path); + $parent = &self::findMenuItemReferenceByPath($menu, $parentPath); + + if (!$parent) { + $err = sprintf('Cannot find parent item "%s"', $parentPath); + throw new \Exception($err); + } + + $parent['child'][] = $newItem; + } + } + + /** + * Moves a menu item to before another specified menu item + * + * @param $menu + * The full menu structure + * @param $itemToMovePath + * The path to the menu item we want to move + * @param $followingItemPath + * The path to the item that the target should be inserted before + */ + public static function relocateBefore( + &$menu, + $itemToMovePath, + $followingItemPath + ) { + self::relocateWithOffset($menu, $itemToMovePath, $followingItemPath, -1); + } + + /** + * Moves a menu item to after another specified menu item + * + * @param array $menu + * The full menu structure + * @param string $itemToMovePath + * The path to the menu item we want to move + * @param string $precedingItemPath + * The path to the item that the target should be inserted after + */ + public static function relocateAfter( + &$menu, + $itemToMovePath, + $precedingItemPath + ) { + self::relocateWithOffset($menu, $itemToMovePath, $precedingItemPath, 1); + } + + /** + * Moves a given item to the same submenu as another target item. Can be + * placed before or after the target item using an offset. + * + * @param $menu + * The full menu structure + * @param $itemToMovePath + * The path to the menu item we want to move + * @param $targetSiblingPath + * The path to the sibling the item will be moved next to + * @param int $offset + * How many places the item should be before / after the sibling item. Use + * 1 to place it right after it, -1 to put before it + */ + private static function relocateWithOffset( + &$menu, + $itemToMovePath, + $targetSiblingPath, + $offset + ) { + if ($offset === 0) { + throw new \Exception('Offset cannot be zero'); + } + + $siblings = &self::getSiblingsReference($menu, $targetSiblingPath); + $itemToMove = self::findMenuItemByPath($menu, $itemToMovePath); + + // remove original from the menu + self::remove($menu, $itemToMovePath); + + // re-index and find point to insert the new item + $siblings = array_values($siblings); + $precedingItemName = self::getItemNameFromPath($targetSiblingPath); + $insertionIndex = self::getMenuItemIndex($siblings, $precedingItemName); + + if (NULL === $insertionIndex) { + $err = sprintf('Could not find menu item "%s"', $targetSiblingPath); + throw new \Exception($err); + } + + $insertionIndex += $offset; + + // the offset is fine as it is for positive offsets, but we skip 0 when + // changing from 'insert after' (offset 1) to 'insert before' (offset -1) + // so we need to adjust negative offsets + if ($offset < 0) { + $insertionIndex++; + } + + // insertion index cannot be lower than 0 (the first element) + $insertionIndex = max(0, $insertionIndex); + + array_splice($siblings, $insertionIndex, 0, [$itemToMove]); + } + + /** + * Removes an item from the menu by path + * + * @param array $menu + * @param string $path + */ + public static function remove(&$menu, $path) { + $siblings = &self::getSiblingsReference($menu, $path); + $itemName = self::getItemNameFromPath($path); + + foreach ($siblings as $index => $sibling) { + if ($sibling['attributes']['name'] === $itemName) { + unset($siblings[$index]); + return; + } + } + } + + /** + * Sets the permission on a named menu item + * + * @param array $menu + * The full menu + * @param string $path + * The path to the item, e.g. "Events/Dashboard" + * @param string $newPermission + * The new permission for accessing this item + */ + public static function updatePermissionByPath(&$menu, $path, $newPermission) { + $item = &self::findMenuItemReferenceByPath($menu, $path); + + if (!$item) { + $err = sprintf('Cannot find menu item with path "%s"', $path); + throw new \Exception($err); + } + + $item['attributes']['permission'] = $newPermission; + } + + + /** + * @param array $menu + * The menu array to search in + * @param string $path + * The path to the item, e.g. "Events/Dashboard" + * + * @return array|null + * The menu item if found, or NULL if not + */ + private static function &findMenuItemReferenceByPath(&$menu, $path) { + if ($path === '') { + return $menu; + } + + $path = explode('/', $path); + $submenu = &$menu; + + while (count($path) > 1) { + $parentName = array_shift($path); + $submenu = &self::findMenuItemReferenceByName($submenu, $parentName); + if (!isset($submenu['child'])) { + $null = NULL; // must return reference to variable + + return $null; + } + $submenu = &$submenu['child']; + } + + $itemName = array_shift($path); + $item = &self::findMenuItemReferenceByName($submenu, $itemName); + + return $item; + } + + /** + * Search for a menu item by its name. Returns a reference to the item. + * + * @param array $menu + * The menu to search, can be a submenu of the full structure + * @param string $name + * The name of the item to search for + * + * @return array|null + * The referenced menu item, if found, or null otherwise + */ + private static function &findMenuItemReferenceByName(&$menu, $name) { + foreach ($menu as &$item) { + if ($item['attributes']['name'] === $name) { + return $item; + } + } + + // must return reference to variable + $item = NULL; + + return $item; + } + + /** + * Returns an array containing all sibling items on the same menu level. + * This includes the target item. + * + * @param array $menu + * The full menu structure + * @param string $path + * The path of the menu item whose siblings we want + * + * @return array + */ + private static function &getSiblingsReference(&$menu, $path) { + if (!self::isRootItem($path)) { + $parentPath = self::getParentPathFromPath($path); + $parent = &self::findMenuItemReferenceByPath($menu, $parentPath); + $siblings = &$parent['child']; + } + else { + $siblings = &$menu; + } + + return $siblings; + } + + /** + * Gets the parent path from a given path, e.g. "Events" from + * "Events/Dashboard" + * + * @param string $path + * + * @return string + */ + private static function getParentPathFromPath($path) { + $path = explode('/', $path); + array_pop($path); + + return implode('/', $path); + } + + /** + * Like array_search, but for menu items + * + * @param array $items + * @param string $name + * + * @return bool|int + */ + private static function getMenuItemIndex($items, $name) { + foreach ($items as $index => $sibling) { + if ($sibling['attributes']['name'] === $name) { + return $index; + } + } + + return FALSE; + } + + /** + * Gets the last item name in a menu item path + * + * @param string $path + * The path of the menu item, e.g. "Events/Dashboard" + * + * @return string + * The final item in the path, e.g. "Dashboard" + */ + private static function getItemNameFromPath($path) { + $path = explode('/', $path); + + return end($path); + } + + /** + * Checks whether the given path is a root menu item, i.e. "Home" + * + * @param string $path + * + * @return bool + */ + private static function isRootItem($path) { + return FALSE === strpos($path, '/'); + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/LocalisationPageFilter.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/LocalisationPageFilter.php new file mode 100644 index 00000000000..c14e136b384 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/LocalisationPageFilter.php @@ -0,0 +1,69 @@ +shouldHandle($formName)) { + return; + } + + $this->filterLocalisationOptions($form); + } + + /** + * Checks if the hook should be handled. + * + * @param string $formName + * + * @return bool + */ + private function shouldHandle($formName) { + if ($formName === CRM_Admin_Form_Setting_Localization::class) { + return TRUE; + } + + return FALSE; + } + + /** + * Hide options on localisation page if user does not have required permission + * + * @param CRM_Core_Form $form + */ + private function filterLocalisationOptions($form) { + $canViewAllFields = CRM_Core_Permission::check('access root menu items and configurations '); + + if (! $canViewAllFields) { + $hiddenOptionsStyle = "tr.crm-localization-form-contact_default_language"; + + foreach ($this->restrictedSettings as $setting) { + if ($form->elementExists($setting)) { + $hiddenOptionsStyle .= ", tr.crm-localization-form-block-$setting"; + $form->freeze($setting); + } + } + + $hiddenOptionsStyle .= ' { display: none; }'; + CRM_Core_Resources::singleton()->addStyle($hiddenOptionsStyle); + } + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/OptionEditPathFilter.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/OptionEditPathFilter.php new file mode 100644 index 00000000000..1ac33de29ee --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Hook/BuildForm/OptionEditPathFilter.php @@ -0,0 +1,70 @@ +filterOptionEditPaths($form); + } + + /** + * Loop through the form, removing the 'data-option-edit-path' from form + * elements that reference locked option groups. If this attribute is not set + * then the icon to provide a shortcut to edit this group will not be shown. + * + * @see \CRM_Core_Form_Renderer::addOptionsEditLink + * + * @param CRM_Core_Form $form + */ + private function filterOptionEditPaths($form) { + /** @var HTML_QuickForm_element $element */ + foreach ($form->_elements as &$element) { + $optionEditPath = $element->getAttribute('data-option-edit-path'); + if (!$optionEditPath) { + continue; + } + + $prefix = 'civicrm/admin/options/'; + if (strpos($optionEditPath, $prefix) !== 0) { + // this is not an option group edit link + continue; + } + + $optionGroupName = str_replace($prefix, '', $optionEditPath); + + if ($this->isLockedOptionGroup($optionGroupName)) { + $element->removeAttribute('data-option-edit-path'); + } + } + } + + /** + * Check whether a given option group is locked + * + * @param string $optionGroupName + * + * @return bool + */ + private function isLockedOptionGroup($optionGroupName) { + if (empty($this->lockedOptionGroups)) { + $params = ['return' => 'name', 'is_locked' => 1]; + $result = civicrm_api3('OptionGroup', 'get', $params)['values']; + $this->lockedOptionGroups = array_column($result, 'name', 'id'); + } + + return in_array($optionGroupName, $this->lockedOptionGroups); + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader.php index e15a417dc7b..5380585a61e 100755 --- a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader.php +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader.php @@ -19,6 +19,11 @@ class CRM_HRCore_Upgrader extends CRM_HRCore_Upgrader_Base { use CRM_HRCore_Upgrader_Steps_1009; use CRM_HRCore_Upgrader_Steps_1010; use CRM_HRCore_Upgrader_Steps_1011; + use CRM_HRCore_Upgrader_Steps_1012; + use CRM_HRCore_Upgrader_Steps_1013; + use CRM_HRCore_Upgrader_Steps_1014; + use CRM_HRCore_Upgrader_Steps_1015; + use CRM_HRCore_Upgrader_Steps_1016; /** * @var array diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1008.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1008.php index ea061c7e4fe..d1229dc0946 100644 --- a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1008.php +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1008.php @@ -8,13 +8,21 @@ trait CRM_HRCore_Upgrader_Steps_1008 { * @return bool */ public function upgrade_1008() { - civicrm_api3('RelationshipType', 'get', [ + $type = civicrm_api3('RelationshipType', 'get', [ 'sequential' => 1, 'name_a_b' => 'Line Manager is', 'name_b_a' => 'Line Manager', - 'api.RelationshipType.create' => ['id' => '$value.id', 'is_reserved' => 1], ]); + if ($type['count'] != 1) { + return TRUE; + } + + $type = array_shift($type['values']); + $type['is_reserved'] = 1; + + civicrm_api3('RelationshipType', 'create', $type); + return TRUE; } } diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1012.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1012.php new file mode 100644 index 00000000000..4313fbaed5d --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1012.php @@ -0,0 +1,144 @@ + 'id', 'name' => 'Administer', 'domain_id' => $domain]; + $administerId = (int) civicrm_api3('Navigation', 'getvalue', $params); + + $this->up1012_addLocalisationShortcut($administerId); + $this->up1012_addOtherStaffDetailsSubmenu($administerId); + $this->up1012_addCustomFieldsShortcut($administerId); + + return TRUE; + } + + /** + * Adds a shortcut to the localization page + * + * @param int $administerId + */ + private function up1012_addLocalisationShortcut($administerId) { + $result = $this->up1012_createNavItem( + 'Localise CiviCRM', + 'access CiviCRM', + $administerId, + ['url' => 'civicrm/admin/setting/localization?reset=1'] + ); + + // weight cannot be set when you're creating first time + $id = $result['id']; + civicrm_api3('Navigation', 'create', ['id' => $id, 'weight' => -101]); + } + + /** + * @param $administerId + * @throws CiviCRM_API3_Exception + */ + private function up1012_addOtherStaffDetailsSubmenu($administerId) { + $permission = 'access CiviCRM'; + $parentName = 'Other Staff Details'; + $parent = $this->up1012_createNavItem($parentName, $permission, $administerId); + $parentId = $parent['id']; + + // Weight cannot be set when creating for the first time + civicrm_api3('Navigation', 'create', ['id' => $parentId, 'weight' => -98]); + + // If we don't flush it will not recognize newly created parent_id + CRM_Core_PseudoConstant::flush(); + + $childLinks = [ + 'Prefixes' => + $this->up1012_getOptionGroupLink('individual_prefix'), + 'Genders' => + $this->up1012_getOptionGroupLink('gender'), + 'Emergency Contact Relationships' => + $this->up1012_getOptionGroupLink('relationship_with_employee_20150304120408'), + 'Manager Types' => + 'civicrm/admin/reltype?reset=1', + 'Career History' => + $this->up1012_getOptionGroupLink('occupation_type_20130617111138'), + 'Disability Types' => + $this->up1012_getOptionGroupLink('type_20130502151940'), + 'Qualifications – Skill Categories' => + $this->up1012_getOptionGroupLink('category_of_skill_20130510015438'), + 'Qualifications – Skill Levels' => + $this->up1012_getOptionGroupLink('level_of_skill_20130510015934'), + ]; + + foreach ($childLinks as $itemName => $link) { + $params = ['url' => $link]; + $this->up1012_createNavItem($itemName, $permission, $parentId, $params); + } + } + + /** + * Adds a shortcut to the edit custom groups + fields page + * + * @param int $administerId + */ + private function up1012_addCustomFieldsShortcut($administerId) { + $result = $this->up1012_createNavItem( + 'Custom Fields', + 'administer CiviCRM', + $administerId, + ['url' => 'civicrm/admin/custom/group?reset=1'] + ); + + // weight cannot be set when you're creating first time + $id = $result['id']; + civicrm_api3('Navigation', 'create', ['id' => $id, 'weight' => -95]); + } + + /** + * Gets the link to edit an option group + * + * @param string $groupName + * + * @return string + */ + private function up1012_getOptionGroupLink($groupName) { + return 'civicrm/admin/options/' . $groupName . '?reset=1'; + } + + /** + * Creates a navigation menu item using the API + * + * @param string $name + * @param string $permission + * @param int $parentID + * @param array $params + * + * @return array + */ + private function up1012_createNavItem( + $name, + $permission, + $parentID, + $params = [] + ) { + $params = array_merge([ + 'name' => $name, + 'label' => ts($name), + 'permission' => $permission, + 'parent_id' => $parentID, + 'is_active' => 1, + ], $params); + + $existing = civicrm_api3('Navigation', 'get', $params); + + if ($existing['count'] > 0) { + return array_shift($existing['values']); + } + + return civicrm_api3('Navigation', 'create', $params); + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1013.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1013.php new file mode 100644 index 00000000000..7127dd7c34d --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1013.php @@ -0,0 +1,65 @@ + 'id', 'name' => 'Administer', 'domain_id' => $domain]; + $administerId = (int) civicrm_api3('Navigation', 'getvalue', $params); + + // If running two consecutive upgraders, items from first are not found + CRM_Core_PseudoConstant::flush(); + + $this->up1013_replaceExistingAdministerItemsPermission($administerId); + + return TRUE; + } + + /** + * Replaces all existing 'administer CiviCRM' permissions in the + * 'Administer' submenu with 'access root menu items and configurations' + * + * @param int $administerId + */ + private function up1013_replaceExistingAdministerItemsPermission($administerId) { + $allChildren = []; + $this->up1013_findAllChildElements($administerId, $allChildren); + $replacement = 'access root menu items and configurations'; + $original = 'administer CiviCRM'; + + $exceptions = ['Custom Fields']; + + foreach ($allChildren as $child) { + if (in_array($child['name'], $exceptions)) { + continue; + } + + $permissions = CRM_Utils_Array::value('permission', $child); + $permissions = str_replace($original, $replacement, $permissions); + $params = ['id' => $child['id'], 'permission' => $permissions]; + civicrm_api3('Navigation', 'create', $params); + } + } + + /** + * Recursively search for all children of a given parent ID + * + * @param int $parentId + * @param array $allChildren + */ + private function up1013_findAllChildElements($parentId, &$allChildren) { + $params = ['parent_id' => $parentId]; + $children = civicrm_api3('Navigation', 'get', $params)['values']; + $allChildren = array_merge($allChildren, $children); + + foreach ($children as $child) { + $this->up1013_findAllChildElements($child['id'], $allChildren); + } + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1014.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1014.php new file mode 100644 index 00000000000..d354c323bd6 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1014.php @@ -0,0 +1,33 @@ + + ['id'], + 'name' => 'Identify', + ]); + + /** + * 'is_multiple' is added to prevent bug that changes it to false + * @see https://issues.civicrm.org/jira/browse/CRM-21853 + */ + if ($result['id']) { + civicrm_api3('CustomGroup', 'create', [ + 'id' => $result['id'], + 'is_reserved' => 1, + 'is_multiple' => 1, + ]); + } + + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1015.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1015.php new file mode 100644 index 00000000000..0ba9cc74b96 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1015.php @@ -0,0 +1,25 @@ + '$value.id', + 'is_locked' => 1, + 'is_active' => 1 + ]; + civicrm_api3('OptionGroup', 'get', [ + 'return' => ['id'], + 'name' => 'phone_type', + 'api.OptionGroup.create' => $data, + ]); + + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1016.php b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1016.php new file mode 100644 index 00000000000..ba6ffb57bc5 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/CRM/HRCore/Upgrader/Steps/1016.php @@ -0,0 +1,92 @@ +up1016_getRelationshipTypesToBeDisabled(); + + $this->up1016_disableRelationshipTypes($relationshipTypesToBeDisabled); + $this->up1016_removeRelationshipsForTypes($relationshipTypesToBeDisabled); + + return TRUE; + } + + /** + * Returns the Ids of the the relationship types to be disabled. + * + * @return int[] + */ + private function up1016_getRelationshipTypesToBeDisabled() { + $relationshipsToBeDeleted = [ + 'Case Coordinator is', + 'Employee of', + 'Head of Household for', + 'Household member of' + ]; + + $result = civicrm_api3('RelationshipType', 'get', [ + 'name_a_b' => [ 'IN' => $relationshipsToBeDeleted ] + ]); + + return array_column($result['values'], 'id'); + } + + /** + * Disables relationship types. + * + * @param int[] $relationshipTypeIds + */ + private function up1016_disableRelationshipTypes($relationshipTypeIds) { + foreach ($relationshipTypeIds as $relationshipTypeId) { + civicrm_api3('RelationshipType', 'create', [ + 'id' => $relationshipTypeId, + 'is_active' => 0 + ]); + } + } + + /** + * Removes relationships for the given relationship types. + * + * @param int[] $relationshipTypeIds + */ + private function up1016_removeRelationshipsForTypes($relationshipTypeIds) { + foreach ($relationshipTypeIds as $relationshipTypeId) { + $relationships = $this->up1016_getRelationshipsForType($relationshipTypeId); + $this->up1016_removeRelationships($relationships); + } + } + + /** + * Returns all the relationships associated with a given type. + * + * @param int $relationshipTypeId + * + * @return array + */ + private function up1016_getRelationshipsForType($relationshipTypeId) { + $result = civicrm_api3('Relationship', 'get', [ + 'relationship_type_id' => $relationshipTypeId + ]); + + return $result['values']; + } + + /** + * Removes the relationships provided. + * + * @param array $relationships + */ + private function up1016_removeRelationships($relationships) { + foreach ($relationships as $relationship) { + civicrm_api3('Relationship', 'delete', [ + 'id' => $relationship['id'] + ]); + } + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-manager-leave-requests.js b/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-manager-leave-requests.js index f8de09a4b15..8d0d4613081 100644 --- a/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-manager-leave-requests.js +++ b/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-manager-leave-requests.js @@ -101,7 +101,8 @@ module.exports = (function () { }, /** * Apply leave on behalf of staff - * @param {String} row number corresponding to leave request in the list like leave, sickness or toil + * + * @param {String} leaveType leave, sickness or toil * @return {Promise} */ applyLeaveForStaff: function (leaveType) { @@ -109,15 +110,11 @@ module.exports = (function () { return new Promise(function (resolve) { casper.then(function () { - var selector = '.button-container leave-request-record-actions .dropdown-toggle'; - - casper.click(selector); + casper.click('leave-request-record-actions .dropdown-toggle'); }); casper.then(function () { - var leaveSerialNo = leaveType === 'leave' ? 1 : leaveType === 'sickness' ? 2 : 3; - - casper.click('.button-container li:nth-child(' + leaveSerialNo + ') a'); + casper.click('.leave-request-record-actions__new-' + leaveType); }); casper.then(function () { diff --git a/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-my-leave-report.js b/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-my-leave-report.js index 3653bab3874..d524e021320 100644 --- a/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-my-leave-report.js +++ b/uk.co.compucorp.civicrm.hrcore/backstop_data/page-objects/ssp-leave-absences-my-leave-report.js @@ -71,17 +71,17 @@ module.exports = (function () { */ newRequest: function (requestType) { var casper = this.casper; - var requestTypes = ['leave', 'sickness', 'toil']; // must be in the same quantity and order as in UI - var requestTypeButtonIndex = requestTypes.indexOf(requestType) + 1; - var actionDropdownSelector = 'leave-request-record-actions'; - var actionButtonSelector = actionDropdownSelector + ' .dropdown-menu a:nth-child(' + requestTypeButtonIndex + ')'; casper.then(function () { - casper.click(actionDropdownSelector + ' [uib-dropdown] > button'); - casper.waitForSelector(actionButtonSelector, function () { - casper.click(actionButtonSelector); - casper.waitUntilVisible('.chr_leave-request-modal__tab .form-group'); - }); + casper.click('leave-request-record-actions .dropdown-toggle'); + }); + + casper.then(function () { + casper.click('.leave-request-record-actions__new-' + requestType); + }); + + casper.then(function () { + casper.waitUntilVisible('.chr_leave-request-modal__tab .form-group'); }); return this; diff --git a/uk.co.compucorp.civicrm.hrcore/hrcore.civix.php b/uk.co.compucorp.civicrm.hrcore/hrcore.civix.php index 2b5dcccfba6..49a45eef221 100644 --- a/uk.co.compucorp.civicrm.hrcore/hrcore.civix.php +++ b/uk.co.compucorp.civicrm.hrcore/hrcore.civix.php @@ -292,7 +292,9 @@ function _hrcore_civix_insert_navigation_menu(&$menu, $path, $item) { $first = array_shift($path); foreach ($menu as $key => &$entry) { if ($entry['attributes']['name'] == $first) { - if (!$entry['child']) $entry['child'] = array(); + if (!isset($entry['child'])) { + $entry['child'] = array(); + } $found = _hrcore_civix_insert_navigation_menu($entry['child'], implode('/', $path), $item, $key); } } diff --git a/uk.co.compucorp.civicrm.hrcore/hrcore.php b/uk.co.compucorp.civicrm.hrcore/hrcore.php index 3ef44d449fe..2a57939d13a 100644 --- a/uk.co.compucorp.civicrm.hrcore/hrcore.php +++ b/uk.co.compucorp.civicrm.hrcore/hrcore.php @@ -10,6 +10,8 @@ use CRM_HRContactActionsMenu_Component_Menu as ActionsMenu; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use CRM_HRContactActionsMenu_Helper_Contact as ContactHelper; +use CRM_HRCore_CMSData_UserRoleFactory as CMSUserRoleFactory; /** * Implements hook_civicrm_config(). @@ -107,15 +109,17 @@ function hrcore_civicrm_container($container) { } /** - * Implements hook_civicrm_buildForm + * Implements hook_civicrm_buildForm(). * * @param string $formName - * @param object $form + * @param CRM_Core_Form $form */ function hrcore_civicrm_buildForm($formName, &$form) { $listeners = [ new CRM_HRCore_Hook_BuildForm_ActivityFilterSelectFieldsModifier(), new CRM_HRCore_Hook_BuildForm_ActivityLinksFilter(), + new CRM_HRCore_Hook_BuildForm_LocalisationPageFilter(), + new CRM_HRCore_Hook_BuildForm_OptionEditPathFilter(), ]; foreach ($listeners as $currentListener) { @@ -268,12 +272,27 @@ function hrcore_civicrm_pre($op, $objectName, $objectId, &$params) { } /** - * Implements hrcore_civicrm_pageRun. + * Implements hrcore_civicrm_pageRun() * - * @link https://docs.civicrm.org/dev/en/master/hooks/hook_civicrm_pageRun/ + * @param CRM_Core_Page $page */ function hrcore_civicrm_pageRun($page) { _hrcore_add_js_session_vars(); + + $contactID = CRM_Core_Session::getLoggedInContactID(); + + $isRoot = FALSE; + if ($contactID) { + $framework = CRM_Core_Config::singleton()->userFramework; + $userInfo = ContactHelper::getUserInformation($contactID); + $roleService = CMSUserRoleFactory::create($framework, $userInfo); + $userRoles = $roleService->getRoles(); + $isRoot = in_array('administrator', $userRoles); + } + + // assign these variables for use in all pages (in use in the footer) + $page->assign('isRoot', $isRoot); + $page->assign('canAccessCiviCRM', CRM_Core_Permission::check('access CiviCRM')); } /** @@ -309,11 +328,13 @@ function hrcore_civicrm_alterMenu(&$items) { * Implements hook_civicrm_permission(). * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_permission/ + * + * @param array $permissions */ function hrcore_civicrm_permission(&$permissions) { - $permissions += [ - 'access CiviCRM developer menu and tools' => ts('Access CiviCRM developer menu and tools') - ]; + $prefix = ts('CiviHR') . ': '; + $permissions['access CiviCRM developer menu and tools'] = ts('Access CiviCRM developer menu and tools'); + $permissions['access root menu items and configurations'] = $prefix . ts('Access root menu items and configurations'); } /** @@ -425,7 +446,7 @@ function _hrcore_createHelpMenu(&$menu) { 'name' => ts('CiviHR website'), 'url' => 'https://www.civihr.org/', 'target' => '_blank', - 'permission' => 'access CiviCRM' + 'permission' => 'access root menu items and configurations' ]); _hrcore_civix_insert_navigation_menu($menu, 'Help', [ diff --git a/uk.co.compucorp.civicrm.hrcore/info.xml b/uk.co.compucorp.civicrm.hrcore/info.xml index aa25c303ad0..8b35f4f7e8c 100644 --- a/uk.co.compucorp.civicrm.hrcore/info.xml +++ b/uk.co.compucorp.civicrm.hrcore/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/uk.co.compucorp.civicrm.hrcore/package-lock.json b/uk.co.compucorp.civicrm.hrcore/package-lock.json index b499d5c57d4..bddabece23f 100644 --- a/uk.co.compucorp.civicrm.hrcore/package-lock.json +++ b/uk.co.compucorp.civicrm.hrcore/package-lock.json @@ -16,20 +16,16 @@ "dev": true }, "@types/node": { - "version": "6.0.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.66.tgz", - "integrity": "sha1-VoC3SmE10z1MAER+fD3GkaRgFiU=", + "version": "9.6.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.7.tgz", + "integrity": "sha512-MuUfEDBrQ/hb7KOqMiDeItAuRxlilQUgNRthTSCU4HgilH8UBh7wiHxWrv/lcyHyFZcREaODVVRNrAunphVwlg==", "dev": true }, - "JSONStream": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", - "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", - "dev": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" - } + "@types/rimraf": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-0.0.28.tgz", + "integrity": "sha1-VWJRm8eWPKyoq/fxKMrjtZTUHQY=", + "dev": true }, "abbrev": { "version": "1.1.1", @@ -38,19 +34,19 @@ "dev": true }, "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "2.1.17", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true }, "acorn-dynamic-import": { @@ -60,6 +56,14 @@ "dev": true, "requires": { "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } } }, "addressparser": { @@ -76,21 +80,12 @@ "dev": true }, "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", - "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", "dev": true, "requires": { - "extend": "3.0.1", - "semver": "5.0.3" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "dev": true - } + "es6-promisify": "5.0.0" } }, "ajv": { @@ -100,7 +95,7 @@ "dev": true, "requires": { "co": "4.6.0", - "fast-deep-equal": "1.0.0", + "fast-deep-equal": "1.1.0", "fast-json-stable-stringify": "2.0.0", "json-schema-traverse": "0.3.1" } @@ -153,13 +148,6 @@ "safe-buffer": "5.1.1" }, "dependencies": { - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true, - "optional": true - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -190,9 +178,9 @@ } }, "ansi-colors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.0.1.tgz", - "integrity": "sha512-yopkAU0ZD/WQ56Tms3xLn6jRuX3SyUMAVi0FdmDIbmmnHW3jHiI1sQFdUl3gfVddjnrsP3Y6ywFKvCRopvoVIA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, "requires": { "ansi-wrap": "0.1.0" @@ -250,104 +238,13 @@ "dev": true }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "2.3.11", + "micromatch": "3.1.5", "normalize-path": "2.1.1" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - } } }, "aproba": { @@ -402,12 +299,6 @@ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", "dev": true }, - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true - }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -427,21 +318,9 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.10.0" + "es-abstract": "1.11.0" } }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", @@ -469,6 +348,12 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -488,14 +373,14 @@ "dev": true }, "asn1.js": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", - "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { "bn.js": "4.11.8", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -520,28 +405,19 @@ "dev": true }, "ast-types": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz", - "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", + "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", "dev": true, "optional": true }, - "astw": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", - "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", - "dev": true, - "requires": { - "acorn": "4.0.13" - } - }, "async": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", - "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", "dev": true, "requires": { - "lodash": "4.17.4" + "lodash": "4.17.10" } }, "async-chain-proxy": { @@ -590,9 +466,9 @@ "dev": true }, "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", "dev": true }, "axios": { @@ -603,6 +479,18 @@ "optional": true, "requires": { "follow-redirects": "1.0.0" + }, + "dependencies": { + "follow-redirects": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", + "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9" + } + } } }, "babel-polyfill": { @@ -612,8 +500,16 @@ "dev": true, "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.3", + "core-js": "2.5.5", "regenerator-runtime": "0.10.5" + }, + "dependencies": { + "core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", + "dev": true + } } }, "babel-runtime": { @@ -622,10 +518,16 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "2.5.3", + "core-js": "2.5.5", "regenerator-runtime": "0.11.1" }, "dependencies": { + "core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", + "dev": true + }, "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", @@ -640,19 +542,29 @@ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", "dev": true }, + "backstop-twentytwenty": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/backstop-twentytwenty/-/backstop-twentytwenty-1.0.4.tgz", + "integrity": "sha512-sENfpossNAbVKZjTzBU6bkbR1vIb7t6brjqH9ZMEIYh/RyCIGFM3BSgERzh+tdwpAVXHSbIV1gQRrtzBYzUrjw==", + "dev": true, + "requires": { + "react": "15.6.2" + } + }, "backstopjs": { - "version": "3.1.19", - "resolved": "https://registry.npmjs.org/backstopjs/-/backstopjs-3.1.19.tgz", - "integrity": "sha512-IBOq69xz32OEXVgMN84dGYWq42PaQIew1rEhsecZ8GyOqYkw8hbGp3+iDhix0w3lFKK9F0N3ySdkdzlSPnHY5g==", + "version": "3.2.15", + "resolved": "https://registry.npmjs.org/backstopjs/-/backstopjs-3.2.15.tgz", + "integrity": "sha512-VLpW9z8T3AbKsFIh3RcvV4Fuo0zFWTRzOpiincO9zheqlI6tXskZeHwotTc3dsBYbI1YSxMPyn8Ytam7eN07Dg==", "dev": true, "requires": { + "backstop-twentytwenty": "1.0.4", "casperjs": "1.1.4", "chalk": "1.1.3", - "chromy": "0.5.7", + "chromy": "0.5.11", "fs-extra": "0.30.0", "jump.js": "1.0.2", "junitwriter": "0.3.1", - "lodash": "4.17.4", + "lodash": "4.17.10", "minimist": "1.2.0", "node-resemble-js": "0.2.0", "object-hash": "1.1.5", @@ -661,13 +573,13 @@ "p-map": "1.2.0", "path": "0.12.7", "phantomjs-prebuilt": "2.1.16", + "puppeteer": "1.3.0", "react": "15.6.2", "react-dom": "15.6.2", - "react-modal": "3.3.1", + "react-modal": "3.4.4", "react-redux": "5.0.7", - "react-sticky": "6.0.1", + "react-sticky": "6.0.2", "react-toggle-button": "2.2.0", - "react-twentytwenty": "1.1.0", "redux": "3.7.2", "sinon": "1.17.7", "styled-components": "2.4.0", @@ -704,9 +616,9 @@ "dev": true }, "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, "base64id": { @@ -829,6 +741,12 @@ "inherits": "2.0.3" } }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, "bmp-js": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.0.3.tgz", @@ -851,12 +769,20 @@ "content-type": "1.0.4", "debug": "2.6.9", "depd": "1.1.2", - "http-errors": "1.6.2", + "http-errors": "1.6.3", "iconv-lite": "0.4.19", "on-finished": "2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "1.6.15" + "type-is": "1.6.16" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + } } }, "bonjour": { @@ -879,7 +805,7 @@ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } }, "brace-expansion": { @@ -917,171 +843,35 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, - "browser-pack": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.3.tgz", - "integrity": "sha512-Jo+RYsn8X8OhyP9tMXXg0ueR2fW696HUu1Hf3/DeiwNean1oGiPtdgGRNuUHBpPHzBH3x4n1kzAlgOgHSIq88g==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.8.0", - "defined": "1.0.0", - "safe-buffer": "5.1.1", - "through2": "2.0.3", - "umd": "3.0.1" - } - }, - "browser-resolve": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", - "dev": true, - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "browserify": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", - "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "assert": "1.4.1", - "browser-pack": "6.0.3", - "browser-resolve": "1.11.2", - "browserify-zlib": "0.2.0", - "buffer": "5.0.8", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "defined": "1.0.0", - "deps-sort": "2.0.0", - "domain-browser": "1.1.7", - "duplexer2": "0.1.4", - "events": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "htmlescape": "1.1.1", - "https-browserify": "1.0.0", - "inherits": "2.0.3", - "insert-module-globals": "7.0.1", - "labeled-stream-splicer": "2.0.0", - "module-deps": "4.1.1", - "os-browserify": "0.3.0", - "parents": "1.0.1", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", - "resolve": "1.5.0", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.8.0", - "string_decoder": "1.0.3", - "subarg": "1.0.0", - "syntax-error": "1.3.0", - "through2": "2.0.3", - "timers-browserify": "1.4.2", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4", - "xtend": "4.0.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - } - } - }, "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", "inherits": "2.0.3", "safe-buffer": "5.1.1" } }, "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", "evp_bytestokey": "1.0.3" } }, "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", + "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { "cipher-base": "1.0.4", @@ -1107,11 +897,11 @@ "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", "elliptic": "6.4.0", "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "parse-asn1": "5.1.1" } }, "browserify-zlib": { @@ -1124,13 +914,13 @@ } }, "buffer": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz", - "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", + "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8" + "base64-js": "1.3.0", + "ieee754": "1.1.11" } }, "buffer-equal": { @@ -1208,12 +998,6 @@ "unset-value": "1.0.0" } }, - "cached-path-relative": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", - "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", - "dev": true - }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -1287,78 +1071,77 @@ "dev": true, "requires": { "cross-spawn": "4.0.2", - "node-version": "1.1.0", + "node-version": "1.1.3", "promise-polyfill": "6.1.0" } }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", "dev": true, "requires": { - "anymatch": "1.3.2", + "anymatch": "2.0.0", "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", + "braces": "2.3.0", + "fsevents": "1.2.2", + "glob-parent": "3.1.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", - "is-glob": "2.0.1", + "is-glob": "4.0.0", + "normalize-path": "2.1.1", "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "readdirp": "2.1.0", + "upath": "1.0.4" }, "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "2.1.1" } } } }, "chrome-launcher": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.4.0.tgz", - "integrity": "sha512-Uq34nQ2peVRwyjsyoLs01mL9aEQDbc5RCZWNyYjGPt5ZFPL2B4OazSc98hO6HZOvMUILLL4MyAEVMzA5OvwWug==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.10.2.tgz", + "integrity": "sha512-E+kTHlGgtitPPu8Rci0E4XBasirKtTn6DjqFn8tTLp/7xCUzqb6lig9Il+HLkcudzKvT/aLxJbzbyNCe03w1AA==", "dev": true, "requires": { "@types/core-js": "0.9.46", "@types/mkdirp": "0.3.29", - "@types/node": "6.0.66", + "@types/node": "9.6.7", + "@types/rimraf": "0.0.28", + "is-wsl": "1.1.0", "lighthouse-logger": "1.0.1", "mkdirp": "0.5.1", "rimraf": "2.6.2" } }, "chrome-remote-interface": { - "version": "0.23.3", - "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.23.3.tgz", - "integrity": "sha512-Bj3zMOEqJNVOll/5LrtvSdpbXSsCiSdnSQPmKUQDmAofahHczR3Qp5VJaAKrhNC/nlv9jj74aYzxTUPKrez8rA==", + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.25.5.tgz", + "integrity": "sha512-JACehSDwNwanDgWIO1Nvji9Td4KyCUUbQze10dNb8DAG72LmqH3uz7vdgujFKjmax8Q6yu1Xwapb8GODZykTDQ==", "dev": true, "requires": { - "commander": "2.1.0", - "ws": "2.0.3" + "commander": "2.11.0", + "ws": "3.3.3" } }, "chromy": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/chromy/-/chromy-0.5.7.tgz", - "integrity": "sha512-XyK4NQkspOhEIALiO0pUhFjaUjVV0WnYqL79U1tQpcu31O/aRWCYi5m56PjqMKFeDYaLo8wWTWeKFRILKPOatA==", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/chromy/-/chromy-0.5.11.tgz", + "integrity": "sha512-SBz5/xPYgeQiwFGMixPNQcbgnzsRHGCJnZKNJ5S0SmauSUY77/mqA8NjotQa12SZ3tZy0NX2gyGP41BAUWI6Rg==", "dev": true, "requires": { "async-chain-proxy": "0.1.5", "babel-runtime": "6.26.0", - "chrome-launcher": "0.4.0", - "chrome-remote-interface": "0.23.3", + "chrome-launcher": "0.10.2", + "chrome-remote-interface": "0.25.5", "jimp": "0.2.28", "uuid": "3.2.1" } @@ -1374,9 +1157,9 @@ } }, "circular-json": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.1.tgz", - "integrity": "sha512-UjgcRlTAhAkLeXmDe2wK7ktwy/tgAqxiSndTIPiFZuIPLZmzHzWMwUIe9h9m/OokypG7snxCDEuwJshGBdPvaw==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.3.tgz", + "integrity": "sha512-YlxLOimeIoQGHnMe3kbf8qIV2Bj7uXLbljMPRguNT49GmSAzooNfS9EJ91rSJKbLBOOzM5agvtx0WyechZN/Hw==", "dev": true }, "civicrm-cv": { @@ -1476,14 +1259,14 @@ } }, "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" } }, "clone": { @@ -1544,9 +1327,9 @@ "dev": true }, "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", + "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==", "dev": true }, "combine-lists": { @@ -1555,34 +1338,22 @@ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "4.17.4" - } - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", - "dev": true, - "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" + "lodash": "4.17.10" } }, "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { "delayed-stream": "1.0.0" } }, "commander": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", - "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "component-bind": { @@ -1610,19 +1381,11 @@ "dev": true, "requires": { "mime-db": "1.33.0" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - } } }, "compression": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.2.tgz", + "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", "dev": true, "requires": { @@ -1633,33 +1396,6 @@ "on-headers": "1.0.1", "safe-buffer": "5.1.1", "vary": "1.1.2" - }, - "dependencies": { - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "2.1.18", - "negotiator": "0.6.1" - } - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - } } }, "concat-map": { @@ -1680,15 +1416,38 @@ } }, "connect": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.5.tgz", - "integrity": "sha1-+43ee6B2OHfQ7J352sC0tA5yx9o=", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", "dev": true, "requires": { "debug": "2.6.9", - "finalhandler": "1.0.6", + "finalhandler": "1.1.0", "parseurl": "1.3.2", "utils-merge": "1.0.1" + }, + "dependencies": { + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } } }, "connect-history-api-fallback": { @@ -1730,12 +1489,6 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - }, "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", @@ -1755,9 +1508,9 @@ "dev": true }, "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", "dev": true }, "core-util-is": { @@ -1767,9 +1520,9 @@ "dev": true }, "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.1.tgz", + "integrity": "sha512-iZvCCg8XqHQZ1ioNBTzXS/cQSkqkqcPs8xSX4upNB+DAk9Ht3uzQf2J32uAHNCne8LDmKr29AgZrEs4oIrwLuQ==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -1777,29 +1530,30 @@ } }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { "cipher-base": "1.0.4", "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.10" + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "inherits": "2.0.3", - "ripemd160": "2.0.1", + "ripemd160": "2.0.2", "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "sha.js": "2.4.11" } }, "create-react-class": { @@ -1827,7 +1581,7 @@ "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "which": "1.3.0" } }, @@ -1846,7 +1600,7 @@ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" } } } @@ -1857,17 +1611,17 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "1.0.0", + "browserify-cipher": "1.0.1", "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", + "create-ecdh": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", "randombytes": "2.0.6", - "randomfill": "1.0.3" + "randomfill": "1.0.4" } }, "css-color-keywords": { @@ -1908,7 +1662,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.39" + "es5-ext": "0.10.42" } }, "dashdash": { @@ -1946,7 +1700,7 @@ "dev": true, "requires": { "get-stdin": "6.0.0", - "meow": "4.0.0" + "meow": "5.0.0" } }, "debug": { @@ -2037,12 +1791,6 @@ "is-descriptor": "1.0.2" } }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, "degenerator": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", @@ -2050,8 +1798,8 @@ "dev": true, "optional": true, "requires": { - "ast-types": "0.10.1", - "escodegen": "1.9.0", + "ast-types": "0.11.3", + "escodegen": "1.9.1", "esprima": "3.1.3" } }, @@ -2063,7 +1811,7 @@ "requires": { "globby": "6.1.0", "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", "p-map": "1.2.0", "pify": "3.0.0", "rimraf": "2.6.2" @@ -2093,18 +1841,6 @@ "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", "dev": true }, - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", - "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "shasum": "1.0.2", - "subarg": "1.0.0", - "through2": "2.0.3" - } - }, "des.js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", @@ -2112,7 +1848,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "destroy": { @@ -2142,24 +1878,6 @@ "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", "dev": true }, - "detective": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", - "dev": true, - "requires": { - "acorn": "5.3.0", - "defined": "1.0.0" - }, - "dependencies": { - "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", - "dev": true - } - } - }, "di": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", @@ -2167,9 +1885,9 @@ "dev": true }, "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -2191,14 +1909,6 @@ "requires": { "ip": "1.1.5", "safe-buffer": "5.1.1" - }, - "dependencies": { - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - } } }, "dns-txt": { @@ -2229,9 +1939,9 @@ "dev": true }, "domain-browser": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", - "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, "double-ended-queue": { @@ -2303,7 +2013,7 @@ "hash.js": "1.1.3", "hmac-drbg": "1.0.1", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -2325,7 +2035,7 @@ "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "dev": true, "requires": { - "iconv-lite": "0.4.19" + "iconv-lite": "0.4.21" } }, "end-of-stream": { @@ -2348,6 +2058,75 @@ } } }, + "engine.io": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", + "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "dev": true, + "requires": { + "accepts": "1.3.5", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", + "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "1.0.2" + } + }, "enhanced-resolve": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", @@ -2390,20 +2169,12 @@ "dev": true, "requires": { "is-arrayish": "0.2.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - } } }, "es-abstract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", - "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", + "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2425,13 +2196,14 @@ } }, "es5-ext": { - "version": "0.10.39", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.39.tgz", - "integrity": "sha512-AlaXZhPHl0po/uxMx1tyrlt1O86M6D5iVaDH8UgLfgek4kXTX6vzsRfJQWC2Ku+aG8pkw1XWzh9eTkwfVrsD5g==", + "version": "0.10.42", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz", + "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==", "dev": true, "requires": { "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" } }, "es6-iterator": { @@ -2441,7 +2213,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39", + "es5-ext": "0.10.42", "es6-symbol": "3.1.1" } }, @@ -2452,7 +2224,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39", + "es5-ext": "0.10.42", "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", @@ -2460,11 +2232,20 @@ } }, "es6-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz", - "integrity": "sha512-LSas5vsuA6Q4nEdf9wokY5/AJYXry98i0IzXsv49rYsgDGDNDPbqAYR1Pe23iFxygfbGZNR/5VrHXBCh2BhvUQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", "dev": true }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "4.2.4" + } + }, "es6-set": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", @@ -2472,7 +2253,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39", + "es5-ext": "0.10.42", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -2485,7 +2266,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39" + "es5-ext": "0.10.42" } }, "es6-weak-map": { @@ -2495,7 +2276,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39", + "es5-ext": "0.10.42", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } @@ -2513,9 +2294,9 @@ "dev": true }, "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", "dev": true, "optional": true, "requires": { @@ -2523,7 +2304,16 @@ "estraverse": "4.2.0", "esutils": "2.0.2", "optionator": "0.8.2", - "source-map": "0.5.7" + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } } }, "escope": { @@ -2579,13 +2369,13 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.39" + "es5-ext": "0.10.42" } }, "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, "events": { @@ -2634,7 +2424,7 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "shebang-command": "1.2.0", "which": "1.3.0" } @@ -2853,9 +2643,9 @@ } }, "express": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", - "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", "dev": true, "requires": { "accepts": "1.3.5", @@ -2870,7 +2660,7 @@ "encodeurl": "1.0.2", "escape-html": "1.0.3", "etag": "1.8.1", - "finalhandler": "1.1.0", + "finalhandler": "1.1.1", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "1.1.2", @@ -2881,72 +2671,20 @@ "qs": "6.5.1", "range-parser": "1.2.0", "safe-buffer": "5.1.1", - "send": "0.16.1", - "serve-static": "1.13.1", + "send": "0.16.2", + "serve-static": "1.13.2", "setprototypeof": "1.1.0", - "statuses": "1.3.1", - "type-is": "1.6.15", + "statuses": "1.4.0", + "type-is": "1.6.16", "utils-merge": "1.0.1", "vary": "1.1.2" }, "dependencies": { - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "2.1.18", - "negotiator": "0.6.1" - } - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", "dev": true - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true } } }, @@ -3028,9 +2766,9 @@ } }, "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { @@ -3070,12 +2808,6 @@ "ua-parser-js": "0.7.17" }, "dependencies": { - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3125,9 +2857,9 @@ } }, "finalhandler": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", - "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { "debug": "2.6.9", @@ -3135,22 +2867,14 @@ "escape-html": "1.0.3", "on-finished": "2.3.0", "parseurl": "1.3.2", - "statuses": "1.3.1", + "statuses": "1.4.0", "unpipe": "1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - } } }, "find": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/find/-/find-0.2.8.tgz", - "integrity": "sha512-7Z96U7PMb7ijrinFZka5N5DWtgziLKdO8EFJSK3AiPqiUkJRcGNofV0/N/Pbe6myimrn7JCpqn+Pvb+Xz9q0NQ==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/find/-/find-0.2.9.tgz", + "integrity": "sha1-S3Px/55WrZG3bnFkB/5f/mVUu4w=", "dev": true, "requires": { "traverse-chain": "0.1.0" @@ -3209,13 +2933,23 @@ "dev": true }, "follow-redirects": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", - "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", + "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", "dev": true, - "optional": true, "requires": { - "debug": "2.6.9" + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "for-each": { @@ -3255,14 +2989,14 @@ "dev": true }, "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "formatio": { @@ -3324,39 +3058,29 @@ "dev": true }, "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.2.tgz", + "integrity": "sha512-iownA+hC4uHFp+7gwP/y5SzaiUo7m2vpa0dhpzw8YuKtiZsz7cIXsFbXpLEeBM6WuCQyw1MH4RRe6XI8GFUctQ==", "dev": true, "optional": true, "requires": { - "nan": "2.8.0", - "node-pre-gyp": "0.6.39" + "nan": "2.10.0", + "node-pre-gyp": "0.9.1" }, "dependencies": { "abbrev": { - "version": "1.1.0", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, "ansi-regex": { "version": "2.1.1", "bundled": true, "dev": true }, "aproba": { - "version": "1.1.1", + "version": "1.2.0", "bundled": true, "dev": true, "optional": true @@ -3368,91 +3092,25 @@ "optional": true, "requires": { "delegates": "1.0.0", - "readable-stream": "2.2.9" + "readable-stream": "2.3.6" } }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, "balanced-match": { - "version": "0.4.2", + "version": "1.0.0", "bundled": true, "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, "brace-expansion": { - "version": "1.1.7", + "version": "1.1.11", "bundled": true, "dev": true, "requires": { - "balanced-match": "0.4.2", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", + "chownr": { + "version": "1.0.1", "bundled": true, "dev": true, "optional": true @@ -3462,14 +3120,6 @@ "bundled": true, "dev": true }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, "concat-map": { "version": "0.0.1", "bundled": true, @@ -3483,35 +3133,11 @@ "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "debug": { - "version": "2.6.8", + "version": "2.6.9", "bundled": true, "dev": true, "optional": true, @@ -3525,11 +3151,6 @@ "dev": true, "optional": true }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, "delegates": { "version": "1.0.0", "bundled": true, @@ -3537,74 +3158,25 @@ "optional": true }, "detect-libc": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", + "version": "1.0.3", "bundled": true, "dev": true, "optional": true }, - "form-data": { - "version": "2.1.4", + "fs-minipass": { + "version": "1.2.5", "bundled": true, "dev": true, "optional": true, "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" + "minipass": "2.2.4" } }, "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } + "optional": true }, "gauge": { "version": "2.7.4", @@ -3612,7 +3184,7 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.1.1", + "aproba": "1.2.0", "console-control-strings": "1.1.0", "has-unicode": "2.0.1", "object-assign": "4.1.1", @@ -3622,27 +3194,11 @@ "wide-align": "1.1.2" } }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, "glob": { "version": "7.1.2", "bundled": true, "dev": true, + "optional": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -3652,193 +3208,96 @@ "path-is-absolute": "1.0.1" } }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, "has-unicode": { "version": "2.0.1", "bundled": true, "dev": true, "optional": true }, - "hawk": { - "version": "3.1.3", + "iconv-lite": { + "version": "0.4.21", "bundled": true, "dev": true, + "optional": true, "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "safer-buffer": "2.1.2" } }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", + "ignore-walk": { + "version": "3.0.1", "bundled": true, "dev": true, "optional": true, "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" + "minimatch": "3.0.4" } }, "inflight": { "version": "1.0.6", "bundled": true, "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, - "jsbn": { - "version": "0.1.1", + "inherits": { + "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, - "json-schema": { - "version": "0.2.3", + "ini": { + "version": "1.3.5", "bundled": true, "dev": true, "optional": true }, - "json-stable-stringify": { - "version": "1.0.1", + "is-fullwidth-code-point": { + "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "jsonify": "0.0.0" + "number-is-nan": "1.0.1" } }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", + "isarray": { + "version": "1.0.0", "bundled": true, "dev": true, "optional": true }, - "jsprim": { - "version": "1.4.0", + "minimatch": { + "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } + "brace-expansion": "1.1.11" } }, - "mime-db": { - "version": "1.27.0", + "minimist": { + "version": "0.0.8", "bundled": true, "dev": true }, - "mime-types": { - "version": "2.1.15", + "minipass": { + "version": "2.2.4", "bundled": true, "dev": true, "requires": { - "mime-db": "1.27.0" + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, - "minimatch": { - "version": "3.0.4", + "minizlib": { + "version": "1.1.0", "bundled": true, "dev": true, + "optional": true, "requires": { - "brace-expansion": "1.1.7" + "minipass": "2.2.4" } }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, "mkdirp": { "version": "0.5.1", "bundled": true, @@ -3853,23 +3312,33 @@ "dev": true, "optional": true }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" + } + }, "node-pre-gyp": { - "version": "0.6.39", + "version": "0.9.1", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", + "detect-libc": "1.0.3", "mkdirp": "0.5.1", + "needle": "2.2.0", "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.6", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" } }, "nopt": { @@ -3878,12 +3347,28 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" } }, "npmlog": { - "version": "4.1.0", + "version": "4.1.2", "bundled": true, "dev": true, "optional": true, @@ -3899,12 +3384,6 @@ "bundled": true, "dev": true }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, "object-assign": { "version": "4.1.1", "bundled": true, @@ -3932,7 +3411,7 @@ "optional": true }, "osenv": { - "version": "0.1.4", + "version": "0.1.5", "bundled": true, "dev": true, "optional": true, @@ -3944,39 +3423,23 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", + "version": "2.0.0", "bundled": true, "dev": true, "optional": true }, "rc": { - "version": "1.2.1", + "version": "1.2.6", "bundled": true, "dev": true, "optional": true, "requires": { "deep-extend": "0.4.2", - "ini": "1.3.4", + "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" }, @@ -3990,112 +3453,63 @@ } }, "readable-stream": { - "version": "2.2.9", + "version": "2.3.6", "bundled": true, "dev": true, + "optional": true, "requires": { - "buffer-shims": "1.0.0", "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, "rimraf": { - "version": "2.6.1", + "version": "2.6.2", "bundled": true, "dev": true, + "optional": true, "requires": { "glob": "7.1.2" } }, "safe-buffer": { - "version": "5.0.1", + "version": "5.1.1", "bundled": true, "dev": true }, - "semver": { - "version": "5.3.0", + "safer-buffer": { + "version": "2.1.2", "bundled": true, "dev": true, "optional": true }, - "set-blocking": { - "version": "2.0.0", + "sax": { + "version": "1.2.4", "bundled": true, "dev": true, "optional": true }, - "signal-exit": { - "version": "3.0.2", + "semver": { + "version": "5.5.0", "bundled": true, "dev": true, "optional": true }, - "sntp": { - "version": "1.0.9", + "set-blocking": { + "version": "2.0.0", "bundled": true, "dev": true, - "requires": { - "hoek": "2.16.3" - } + "optional": true }, - "sshpk": { - "version": "1.13.0", + "signal-exit": { + "version": "3.0.2", "bundled": true, "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "string-width": { "version": "1.0.2", @@ -4108,19 +3522,14 @@ } }, "string_decoder": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "safe-buffer": "5.0.1" + "safe-buffer": "5.1.1" } }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, "strip-ansi": { "version": "3.0.1", "bundled": true, @@ -4136,81 +3545,26 @@ "optional": true }, "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", + "version": "4.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "safe-buffer": "5.0.1" + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, "dev": true, "optional": true }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, "wide-align": { "version": "1.1.2", "bundled": true, @@ -4224,6 +3578,11 @@ "version": "1.0.2", "bundled": true, "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true } } }, @@ -4306,6 +3665,17 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } } } }, @@ -4414,6 +3784,15 @@ "is-glob": "2.0.1" }, "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", @@ -4432,29 +3811,13 @@ } }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "2.0.1" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - } + "is-glob": "3.1.0", + "path-dirname": "1.0.2" } }, "glob-stream": { @@ -4911,7 +4274,7 @@ "integrity": "sha512-qEocs1UVoDKKUjfsxJNMNwkRla0PbsyJwsqNNXpzYWsLQ29LhxRMY3wnTGZcc4hMHtalnvah/Dwlwb4NijH/0A==", "dev": true, "requires": { - "ansi-colors": "1.0.1", + "ansi-colors": "1.1.0", "fancy-log": "1.3.2", "lodash.template": "4.4.0", "node-notifier": "5.2.1", @@ -5009,14 +4372,14 @@ } }, "gulp-sass": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz", - "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.2.1.tgz", + "integrity": "sha512-UATbRpSDsyXCnpYSPBUEvdvtSEzksJs7/oQ0CujIpzKqKrO6vlnYwhX2UTsGrf4rNLwqlSSaM271It0uHYvJ3Q==", "dev": true, "requires": { "gulp-util": "3.0.8", "lodash.clonedeep": "4.5.0", - "node-sass": "4.7.2", + "node-sass": "4.9.0", "through2": "2.0.3", "vinyl-sourcemaps-apply": "0.2.1" } @@ -5321,12 +4684,13 @@ } }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.1" } }, "hash.js": { @@ -5336,7 +4700,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "hasha": { @@ -5357,7 +4721,7 @@ "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", - "hoek": "4.2.0", + "hoek": "4.2.1", "sntp": "2.1.0" } }, @@ -5368,8 +4732,8 @@ "dev": true, "optional": true, "requires": { - "lodash": "4.17.4", - "request": "2.83.0" + "lodash": "4.17.10", + "request": "2.85.0" } }, "hmac-drbg": { @@ -5379,14 +4743,14 @@ "dev": true, "requires": { "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", "dev": true }, "hoist-non-react-statics": { @@ -5405,9 +4769,9 @@ } }, "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "hpack.js": { @@ -5417,9 +4781,9 @@ "dev": true, "requires": { "inherits": "2.0.3", - "obuf": "1.1.1", + "obuf": "1.1.2", "readable-stream": "2.3.3", - "wbuf": "1.7.2" + "wbuf": "1.7.3" } }, "html-entities": { @@ -5428,12 +4792,6 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", - "dev": true - }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -5441,38 +4799,31 @@ "dev": true }, "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - } + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.4.0" } }, "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.12.tgz", + "integrity": "sha1-uc+/Sizybw/DSxDKFImid3HjR08=", "dev": true }, "http-proxy": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", - "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "1.2.0", + "eventemitter3": "3.1.0", + "follow-redirects": "1.4.1", "requires-port": "1.0.0" } }, @@ -5485,6 +4836,24 @@ "agent-base": "2.1.1", "debug": "2.6.9", "extend": "3.0.1" + }, + "dependencies": { + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + } + }, + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + } } }, "http-proxy-middleware": { @@ -5493,9 +4862,9 @@ "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", "dev": true, "requires": { - "http-proxy": "1.16.2", + "http-proxy": "1.17.0", "is-glob": "3.1.0", - "lodash": "4.17.4", + "lodash": "4.17.10", "micromatch": "2.3.11" }, "dependencies": { @@ -5600,7 +4969,7 @@ "requires": { "assert-plus": "1.0.0", "jsprim": "1.4.1", - "sshpk": "1.13.1" + "sshpk": "1.14.1" } }, "httpntlm": { @@ -5626,26 +4995,39 @@ "dev": true }, "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1" + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", + "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", + "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", "dev": true }, "import-local": { @@ -5705,82 +5087,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "insert-module-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", - "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", - "concat-stream": "1.5.2", - "is-buffer": "1.1.6", - "lexical-scope": "1.2.0", - "process": "0.11.10", - "through2": "2.0.3", - "xtend": "4.0.1" - }, - "dependencies": { - "combine-source-map": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", - "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", - "dev": true, - "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" - } - }, - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "internal-ip": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", @@ -5973,9 +5279,9 @@ "dev": true }, "invariant": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", - "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { "loose-envify": "1.3.1" @@ -5988,11 +5294,10 @@ "dev": true }, "ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz", - "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=", - "dev": true, - "optional": true + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true }, "ip-regex": { "version": "1.0.3", @@ -6031,6 +5336,12 @@ "kind-of": "6.0.2" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -6147,14 +5458,21 @@ "is-extglob": "2.1.1" } }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, "is-my-json-valid": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz", - "integrity": "sha512-Q2khNw+oBlWuaYvEEHtKSw/pCxD2L5Rc1C+UQme9X6JdRDh7m5D7HkozA0qa3DUkQ6VzCnEm8mVIQPyIRkI5sQ==", + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", + "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", "dev": true, "requires": { "generate-function": "2.0.0", "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", "jsonpointer": "4.0.1", "xtend": "4.0.1" } @@ -6195,9 +5513,9 @@ "dev": true }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "1.0.1" @@ -6345,7 +5663,7 @@ "dev": true, "requires": { "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" + "whatwg-fetch": "2.0.4" } }, "isstream": { @@ -6365,9 +5683,9 @@ } }, "jasmine-core": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.9.1.tgz", - "integrity": "sha1-trvB2OZSUNVvWIhGFwXr7uuI8i8=", + "version": "2.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", + "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", "dev": true }, "jimp": { @@ -6386,9 +5704,9 @@ "mime": "1.6.0", "mkdirp": "0.5.1", "pixelmatch": "4.0.2", - "pngjs": "3.3.2", + "pngjs": "3.3.3", "read-chunk": "1.0.1", - "request": "2.83.0", + "request": "2.85.0", "stream-to-buffer": "0.1.0", "tinycolor2": "1.4.1", "url-regex": "3.2.0" @@ -6409,9 +5727,9 @@ "dev": true }, "js-base64": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.2.tgz", - "integrity": "sha512-lLkz3IRPTNeATsKQGeltbzRK/5+bWsXBHfpZrxJAi4N30RtCtNA+rJznp4uR2+4OgkBsoeeFwONVLr4gzIVErQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", + "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", "dev": true }, "js-tokens": { @@ -6434,9 +5752,9 @@ "dev": true }, "json-parse-better-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", - "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema": { @@ -6451,15 +5769,6 @@ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -6487,18 +5796,6 @@ "graceful-fs": "4.1.11" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, "jsonpointer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", @@ -6568,32 +5865,31 @@ } }, "karma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.0.tgz", - "integrity": "sha512-K9Kjp8CldLyL9ANSUctDyxC7zH3hpqXj/K09qVf06K3T/kXaHtFZ5tQciK7OzQu68FLvI89Na510kqQ2LCbpIw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.2.tgz", + "integrity": "sha1-TS25QChQpmVR+nhLAWT7CCTtjEs=", "dev": true, "requires": { "bluebird": "3.5.1", "body-parser": "1.18.2", - "browserify": "14.5.0", "chokidar": "1.7.0", - "colors": "1.1.2", + "colors": "1.2.1", "combine-lists": "1.0.1", - "connect": "3.6.5", - "core-js": "2.5.3", + "connect": "3.6.6", + "core-js": "2.5.5", "di": "0.0.1", "dom-serialize": "2.2.1", "expand-braces": "0.1.2", "glob": "7.1.2", "graceful-fs": "4.1.11", - "http-proxy": "1.16.2", + "http-proxy": "1.17.0", "isbinaryfile": "3.0.2", - "lodash": "4.17.4", - "log4js": "2.5.2", + "lodash": "4.17.10", + "log4js": "2.5.3", "mime": "1.6.0", "minimatch": "3.0.4", "optimist": "0.6.1", - "qjobs": "1.1.5", + "qjobs": "1.2.0", "range-parser": "1.2.0", "rimraf": "2.6.2", "safe-buffer": "5.1.1", @@ -6603,229 +5899,141 @@ "useragent": "2.2.1" }, "dependencies": { - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "ms": "2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, - "engine.io": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.4.tgz", - "integrity": "sha1-PQIRtwpVLOhB/8fahiezAamkFi4=", + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.6.9", - "engine.io-parser": "2.1.2", - "uws": "0.14.5", - "ws": "3.3.3" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "arr-flatten": "1.1.0" } }, - "engine.io-client": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.4.tgz", - "integrity": "sha1-T88TcLRxY70s6b4nM5ckMDUNTqE=", + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.6.9", - "engine.io-parser": "2.1.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "3.3.3", - "xmlhttprequest-ssl": "1.5.5", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "1.0.2" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.2.2", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", "dev": true }, - "log4js": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.2.tgz", - "integrity": "sha512-MmZhzQCfCV5+nQgOqy34V9EV3k+Z/rPCdxyq+25EePKpwdUQxCb19BTmL5iX3iOCSAV/tWh7KVYqchwrx3+S2Q==", + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "amqplib": "0.5.2", - "axios": "0.15.3", - "circular-json": "0.5.1", - "date-format": "1.2.0", - "debug": "3.1.0", - "hipchat-notifier": "1.1.0", - "loggly": "1.1.1", - "mailgun-js": "0.7.15", - "nodemailer": "2.7.2", - "redis": "2.8.0", - "semver": "5.5.0", - "slack-node": "0.2.0", - "streamroller": "0.7.0" + "is-posix-bracket": "0.1.1" } }, - "socket.io": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", - "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "debug": "2.6.9", - "engine.io": "3.1.4", - "socket.io-adapter": "1.1.1", - "socket.io-client": "2.0.4", - "socket.io-parser": "3.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "is-extglob": "1.0.0" } }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, - "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.6.9", - "engine.io-client": "3.1.4", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "3.1.2", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "is-extglob": "1.0.0" } }, - "socket.io-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz", - "integrity": "sha1-28IoIVH8T6675Aru3Ady66YZ9/I=", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "component-emitter": "1.2.1", - "debug": "2.6.9", - "has-binary2": "1.0.2", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "is-buffer": "1.1.6" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "dev": true, "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.1", - "ultron": "1.1.1" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" } }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } @@ -6903,25 +6111,6 @@ "graceful-fs": "4.1.11" } }, - "labeled-stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", - "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "isarray": "0.0.1", - "stream-splicer": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "lazy-cache": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", @@ -6951,15 +6140,6 @@ "type-check": "0.3.2" } }, - "lexical-scope": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", - "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", - "dev": true, - "requires": { - "astw": "2.2.0" - } - }, "libbase64": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", @@ -7071,15 +6251,15 @@ } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, "lodash-es": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.5.tgz", - "integrity": "sha512-Ez3ONp3TK9gX1HYKp6IhetcVybD+2F+Yp6GS9dfH8ue6EOCEzQtQEh4K0FYWBP9qLv+lzeQAYXw+3ySfxyZqkw==", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz", + "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg==", "dev": true }, "lodash._basecopy": { @@ -7180,16 +6360,10 @@ "lodash.isarray": "3.0.4" } }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, "lodash.mergewith": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", - "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "dev": true }, "lodash.restparam": { @@ -7225,6 +6399,38 @@ "lodash.escape": "3.2.0" } }, + "log4js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz", + "integrity": "sha512-YL/qpTxYtK0iWWbuKCrevDZz5lh+OjyHHD+mICqpjnYGKdNRBvPeh/1uYjkKUemT1CSO4wwLOwphWMpKAnD9kw==", + "dev": true, + "requires": { + "amqplib": "0.5.2", + "axios": "0.15.3", + "circular-json": "0.5.3", + "date-format": "1.2.0", + "debug": "3.1.0", + "hipchat-notifier": "1.1.0", + "loggly": "1.1.1", + "mailgun-js": "0.7.15", + "nodemailer": "2.7.2", + "redis": "2.8.0", + "semver": "5.5.0", + "slack-node": "0.2.0", + "streamroller": "0.7.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "loggly": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", @@ -7267,13 +6473,6 @@ "dev": true, "optional": true }, - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true, - "optional": true - }, "cryptiles": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", @@ -7292,8 +6491,8 @@ "optional": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "har-validator": { @@ -7304,8 +6503,8 @@ "optional": true, "requires": { "chalk": "1.1.3", - "commander": "2.13.0", - "is-my-json-valid": "2.17.1", + "commander": "2.11.0", + "is-my-json-valid": "2.17.2", "pinkie-promise": "2.0.1" } }, @@ -7337,9 +6536,16 @@ "requires": { "assert-plus": "0.2.0", "jsprim": "1.4.1", - "sshpk": "1.13.1" + "sshpk": "1.14.1" } }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "dev": true, + "optional": true + }, "qs": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", @@ -7355,10 +6561,10 @@ "optional": true, "requires": { "aws-sign2": "0.6.0", - "aws4": "1.6.0", + "aws4": "1.7.0", "bl": "1.1.2", "caseless": "0.11.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", "form-data": "2.0.0", @@ -7368,12 +6574,12 @@ "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "node-uuid": "1.4.8", "oauth-sign": "0.8.2", "qs": "6.2.3", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.4.3" } }, @@ -7434,21 +6640,13 @@ } }, "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", + "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "dev": true, "requires": { "pseudomap": "1.0.2", "yallist": "2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } } }, "mailcomposer": { @@ -7480,6 +6678,16 @@ "tsscmp": "1.0.5" }, "dependencies": { + "async": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", + "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=", + "dev": true, + "optional": true, + "requires": { + "lodash": "4.17.10" + } + }, "debug": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", @@ -7498,8 +6706,8 @@ "optional": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "ms": { @@ -7560,18 +6768,6 @@ "requires": { "hash-base": "3.0.4", "inherits": "2.0.3" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - } } }, "media-typer": { @@ -7586,7 +6782,7 @@ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "mimic-fn": "1.1.0" + "mimic-fn": "1.2.0" } }, "memory-fs": { @@ -7600,20 +6796,20 @@ } }, "meow": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.0.tgz", - "integrity": "sha512-Me/kel335m6vMKmEmA6c87Z6DUFW3JqkINRnxkbC+A/PUm0D5Fl2dEBQrPKnqCL9Te/CIa1MUt/0InMJhuC/sw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", "dev": true, "requires": { "camelcase-keys": "4.2.0", "decamelize-keys": "1.1.0", "loud-rejection": "1.6.0", - "minimist": "1.2.0", "minimist-options": "3.0.2", "normalize-package-data": "2.4.0", "read-pkg-up": "3.0.0", "redent": "2.0.0", - "trim-newlines": "2.0.0" + "trim-newlines": "2.0.0", + "yargs-parser": "10.0.0" } }, "merge": { @@ -7672,24 +6868,24 @@ "dev": true }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "dev": true }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" } }, "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "min-document": { @@ -7702,9 +6898,9 @@ } }, "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "minimalistic-crypto-utils": { @@ -7776,73 +6972,6 @@ } } }, - "module-deps": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", - "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "browser-resolve": "1.11.2", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "defined": "1.0.0", - "detective": "4.7.1", - "duplexer2": "0.1.4", - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.3", - "resolve": "1.5.0", - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", - "xtend": "4.0.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - } - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7875,9 +7004,9 @@ } }, "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", "dev": true }, "nanomatch": { @@ -7920,9 +7049,9 @@ "dev": true }, "neo-async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", - "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", "dev": true }, "netmask": { @@ -7932,6 +7061,12 @@ "dev": true, "optional": true }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", @@ -7961,8 +7096,8 @@ "mkdirp": "0.5.1", "nopt": "3.0.6", "npmlog": "4.1.2", - "osenv": "0.1.4", - "request": "2.83.0", + "osenv": "0.1.5", + "request": "2.85.0", "rimraf": "2.6.2", "semver": "5.3.0", "tar": "2.2.1", @@ -7974,17 +7109,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } } } }, @@ -8000,7 +7124,7 @@ "console-browserify": "1.1.0", "constants-browserify": "1.0.0", "crypto-browserify": "3.12.0", - "domain-browser": "1.1.7", + "domain-browser": "1.2.0", "events": "1.1.1", "https-browserify": "1.0.0", "os-browserify": "0.3.0", @@ -8010,9 +7134,9 @@ "querystring-es3": "0.2.1", "readable-stream": "2.3.3", "stream-browserify": "2.0.1", - "stream-http": "2.8.0", + "stream-http": "2.8.1", "string_decoder": "1.0.3", - "timers-browserify": "2.0.6", + "timers-browserify": "2.0.10", "tty-browserify": "0.0.0", "url": "0.11.0", "util": "0.10.3", @@ -8025,8 +7149,8 @@ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8", + "base64-js": "1.3.0", + "ieee754": "1.1.11", "isarray": "1.0.0" } }, @@ -8035,15 +7159,6 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true - }, - "timers-browserify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz", - "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==", - "dev": true, - "requires": { - "setimmediate": "1.0.5" - } } } }, @@ -8078,9 +7193,9 @@ } }, "node-sass": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz", - "integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.0.tgz", + "integrity": "sha512-QFHfrZl6lqRU3csypwviz2XLgGNOoWQbo2GOvtsfQqOfL4cy1BtWnhx/XUeAO9LT3ahBzSRXcEO6DdvAH9DzSg==", "dev": true, "requires": { "async-foreach": "0.1.3", @@ -8092,10 +7207,10 @@ "in-publish": "2.0.0", "lodash.assign": "4.2.0", "lodash.clonedeep": "4.5.0", - "lodash.mergewith": "4.6.0", + "lodash.mergewith": "4.6.1", "meow": "3.7.0", "mkdirp": "0.5.1", - "nan": "2.8.0", + "nan": "2.10.0", "node-gyp": "3.6.2", "npmlog": "4.1.2", "request": "2.79.0", @@ -8147,19 +7262,13 @@ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", "dev": true }, - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "which": "1.3.0" } }, @@ -8189,8 +7298,8 @@ "dev": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "gaze": { @@ -8215,7 +7324,7 @@ "dev": true, "requires": { "glob": "7.1.2", - "lodash": "4.17.4", + "lodash": "4.17.10", "minimatch": "3.0.4" } }, @@ -8226,8 +7335,8 @@ "dev": true, "requires": { "chalk": "1.1.3", - "commander": "2.13.0", - "is-my-json-valid": "2.17.1", + "commander": "2.11.0", + "is-my-json-valid": "2.17.2", "pinkie-promise": "2.0.1" } }, @@ -8257,7 +7366,7 @@ "requires": { "assert-plus": "0.2.0", "jsprim": "1.4.1", - "sshpk": "1.13.1" + "sshpk": "1.14.1" } }, "indent-string": { @@ -8391,9 +7500,9 @@ "dev": true, "requires": { "aws-sign2": "0.6.0", - "aws4": "1.6.0", + "aws4": "1.7.0", "caseless": "0.11.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", "form-data": "2.1.4", @@ -8403,11 +7512,11 @@ "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "oauth-sign": "0.8.2", "qs": "6.3.2", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.4.3", "uuid": "3.2.1" } @@ -8453,17 +7562,10 @@ } } }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true, - "optional": true - }, "node-version": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.1.0.tgz", - "integrity": "sha512-t1V2RFiaTavaW3jtQO0A2nok6k7/Gghuvx2rjvICuT0B0dYaObBQ4U0xHL+ZTPFZodt1LMYG2Vi2nypfz4/AJg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.1.3.tgz", + "integrity": "sha512-rEwE51JWn0yN3Wl5BXeGn5d52OGbSXzWiiXRjAQeuyvcGKyvuSILW2rb3G7Xh+nexzLwhTpek6Ehxd6IjvHePg==", "dev": true }, "node.extend": { @@ -8491,13 +7593,6 @@ "socks": "1.1.9" }, "dependencies": { - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true, - "optional": true - }, "socks": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", @@ -8582,10 +7677,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.5.0", + "hosted-git-info": "2.6.0", "is-builtin-module": "1.0.0", "semver": "5.5.0", - "validate-npm-package-license": "3.0.1" + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -8790,9 +7885,9 @@ } }, "obuf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz", - "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "dev": true }, "on-finished": { @@ -8826,9 +7921,9 @@ "dev": true }, "opn": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.2.0.tgz", - "integrity": "sha512-Jd/GpzPyHF4P2/aNOVmS3lfMSWV9J7cOhCG1s08XCEAsPkB7lp6ddiU0J7XzyQRDUh8BqJ7PchfINjR8jyofRQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { "is-wsl": "1.1.0" @@ -8841,7 +7936,7 @@ "dev": true, "requires": { "minimist": "0.0.10", - "wordwrap": "0.0.3" + "wordwrap": "0.0.2" }, "dependencies": { "minimist": { @@ -8933,12 +8028,14 @@ "dev": true }, "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", "dev": true, "requires": { - "lcid": "1.0.0" + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" } }, "os-tmpdir": { @@ -8948,9 +8045,9 @@ "dev": true }, "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { "os-homedir": "1.0.2", @@ -9009,6 +8106,36 @@ "pac-resolver": "2.0.0", "raw-body": "2.3.2", "socks-proxy-agent": "2.1.1" + }, + "dependencies": { + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + } + }, + "https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "optional": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1" + } + }, + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + } } }, "pac-resolver": { @@ -9031,6 +8158,13 @@ "integrity": "sha1-FEXyJsXrlWE45oyawwFn6n0ua9o=", "dev": true, "optional": true + }, + "ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz", + "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=", + "dev": true, + "optional": true } } }, @@ -9040,26 +8174,17 @@ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", "dev": true }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { - "path-platform": "0.11.15" - } - }, "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { - "asn1.js": "4.9.2", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "pbkdf2": "3.0.16" } }, "parse-bmfont-ascii": { @@ -9141,7 +8266,7 @@ "dev": true, "requires": { "error-ex": "1.3.1", - "json-parse-better-errors": "1.0.1" + "json-parse-better-errors": "1.0.2" } }, "parse-passwd": { @@ -9240,12 +8365,6 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, "path-proxy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", @@ -9296,16 +8415,16 @@ } }, "pbkdf2": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", - "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", "safe-buffer": "5.1.1", - "sha.js": "2.4.10" + "sha.js": "2.4.11" } }, "pend": { @@ -9326,13 +8445,13 @@ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", "dev": true, "requires": { - "es6-promise": "4.2.2", + "es6-promise": "4.2.4", "extract-zip": "1.6.6", "fs-extra": "1.0.0", "hasha": "2.2.0", "kew": "0.7.0", "progress": "1.1.8", - "request": "2.83.0", + "request": "2.85.0", "request-progress": "2.0.1", "which": "1.3.0" }, @@ -9377,7 +8496,7 @@ "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", "dev": true, "requires": { - "pngjs": "3.3.2" + "pngjs": "3.3.3" } }, "pkg-dir": { @@ -9390,12 +8509,12 @@ } }, "plugin-error": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.0.tgz", - "integrity": "sha1-N9Zr2W6jNLdHJYTbFJZ3uiM3ck4=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", "dev": true, "requires": { - "ansi-colors": "1.0.1", + "ansi-colors": "1.1.0", "arr-diff": "4.0.0", "arr-union": "3.1.0", "extend-shallow": "3.0.2" @@ -9423,9 +8542,9 @@ } }, "pngjs": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.2.tgz", - "integrity": "sha512-bVNd3LMXRzdo6s4ehr4XW2wFMu9cb40nPgHEjSSppm8/++Xc+g0b2QQb+SeDesgfANXbjydOr1or9YQ+pcCZPQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz", + "integrity": "sha512-1n3Z4p3IOxArEs1VRXnZ/RXdfEniAUS9jb68g58FIXMNkPJeZd+Qh4Uq7/e0LVxAQGos1eIUrqrt4FpjdnEd+Q==", "dev": true }, "portfinder": { @@ -9556,15 +8675,49 @@ "socks-proxy-agent": "2.1.1" }, "dependencies": { + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + } + }, + "https-proxy-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", + "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", + "dev": true, + "optional": true, + "requires": { + "agent-base": "2.1.1", + "debug": "2.6.9", + "extend": "3.0.1" + } + }, "lru-cache": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=", "dev": true, "optional": true + }, + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true } } }, + "proxy-from-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", + "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "dev": true + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -9578,15 +8731,15 @@ "dev": true }, "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", "randombytes": "2.0.6" } }, @@ -9596,6 +8749,30 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, + "puppeteer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.3.0.tgz", + "integrity": "sha512-wx10aPQPpGJVxdB6yoDSLm9p4rCwARUSLMVV0bx++owuqkvviXKyiFM3EWsywaFmjOKNPXacIjplF7xhHiFP3w==", + "dev": true, + "requires": { + "debug": "2.6.9", + "extract-zip": "1.6.6", + "https-proxy-agent": "2.2.1", + "mime": "1.6.0", + "progress": "2.0.0", + "proxy-from-env": "1.0.0", + "rimraf": "2.6.2", + "ws": "3.3.3" + }, + "dependencies": { + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + } + } + }, "q": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", @@ -9604,9 +8781,9 @@ "optional": true }, "qjobs": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.1.5.tgz", - "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true }, "qs": { @@ -9679,9 +8856,9 @@ } }, "randomfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", - "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { "randombytes": "2.0.6", @@ -9704,6 +8881,38 @@ "http-errors": "1.6.2", "iconv-lite": "0.4.19", "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } } }, "react": { @@ -9747,14 +8956,21 @@ } } }, + "react-lifecycles-compat": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.2.tgz", + "integrity": "sha512-pbZOSMVVkvppW7XRn9fcHK5OgEDnYLwMva7P6TgS44/SN9uGGjfh3Z1c8tomO+y4IsHQ6Fsz2EGwmE7sMeNZgQ==", + "dev": true + }, "react-modal": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.3.1.tgz", - "integrity": "sha512-d1A8xXIvW+YVKwRMrFY5qneuC5FSa4OnOE78hgqfz+MYLb1Ai/B3D3Dzx1Zrw4ZD5rS16SKiPe5rl4UZt+AjpQ==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.4.4.tgz", + "integrity": "sha512-5VYNvy301Z0xxGBQhPmDdzOcyEkUG8sU7bpRsAPI4OHgEUkbBFrpjzs/ocNI0m824/lOqTxddXzwgmDJXx3s3Q==", "dev": true, "requires": { "exenv": "1.2.2", "prop-types": "15.6.1", + "react-lifecycles-compat": "3.0.2", "warning": "3.0.0" } }, @@ -9784,25 +9000,17 @@ "dev": true, "requires": { "hoist-non-react-statics": "2.5.0", - "invariant": "2.2.3", - "lodash": "4.17.5", - "lodash-es": "4.17.5", + "invariant": "2.2.4", + "lodash": "4.17.10", + "lodash-es": "4.17.10", "loose-envify": "1.3.1", "prop-types": "15.6.1" - }, - "dependencies": { - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", - "dev": true - } } }, "react-sticky": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/react-sticky/-/react-sticky-6.0.1.tgz", - "integrity": "sha1-NWmIvcxvyM0tiXRtIwLtzmfYZoc=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-sticky/-/react-sticky-6.0.2.tgz", + "integrity": "sha512-eXsij6ifE2k1d6eCwQzil0JRS3VLP6BYfiF7qEbVPL3GLqciedGJfbavpXx5T95x5HvhuAA4FChYEDv83r1NyQ==", "dev": true, "requires": { "prop-types": "15.6.1", @@ -9819,30 +9027,12 @@ "react-motion": "0.5.2" } }, - "react-twentytwenty": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/react-twentytwenty/-/react-twentytwenty-1.1.0.tgz", - "integrity": "sha512-cSwoNCygg7K68yBmkIvOC0sPstkwCGlDpvbI93bJEyAuan3zwW7WFMY58uIfQMONz9qtqfcdmoS+Wy/FMpmnVA==", - "dev": true, - "requires": { - "prop-types": "15.6.1" - } - }, "read-chunk": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-1.0.1.tgz", "integrity": "sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=", "dev": true }, - "read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -9918,14 +9108,14 @@ "optional": true, "requires": { "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.1", + "redis-commands": "1.3.5", "redis-parser": "2.6.0" } }, "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", + "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", "dev": true, "optional": true }, @@ -9942,8 +9132,8 @@ "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==", "dev": true, "requires": { - "lodash": "4.17.4", - "lodash-es": "4.17.5", + "lodash": "4.17.10", + "lodash-es": "4.17.10", "loose-envify": "1.3.1", "symbol-observable": "1.2.0" } @@ -10025,31 +9215,31 @@ } }, "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "version": "2.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "dev": true, "requires": { "aws-sign2": "0.7.0", - "aws4": "1.6.0", + "aws4": "1.7.0", "caseless": "0.12.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", - "form-data": "2.3.1", + "form-data": "2.3.2", "har-validator": "5.0.3", "hawk": "6.0.2", "http-signature": "1.2.0", "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "oauth-sign": "0.8.2", "performance-now": "2.1.0", "qs": "6.5.1", "safe-buffer": "5.1.1", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.6.0", "uuid": "3.2.1" } @@ -10071,8 +9261,8 @@ "optional": true, "requires": { "extend": "3.0.1", - "lodash": "4.17.4", - "request": "2.83.0", + "lodash": "4.17.10", + "request": "2.85.0", "when": "3.7.8" } }, @@ -10159,12 +9349,12 @@ } }, "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "2.0.2", + "hash-base": "3.0.4", "inherits": "2.0.3" } }, @@ -10174,6 +9364,12 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "samsam": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", @@ -10187,7 +9383,7 @@ "dev": true, "requires": { "glob": "7.1.2", - "lodash": "4.17.4", + "lodash": "4.17.10", "scss-tokenizer": "0.2.3", "yargs": "7.1.0" }, @@ -10198,6 +9394,17 @@ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -10221,6 +9428,15 @@ "strip-bom": "2.0.0" } }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -10277,6 +9493,17 @@ "read-pkg": "1.1.0" } }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", @@ -10286,6 +9513,12 @@ "is-utf8": "0.2.1" } }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", @@ -10306,6 +9539,15 @@ "y18n": "3.2.1", "yargs-parser": "5.0.0" } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + } } } }, @@ -10321,7 +9563,7 @@ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "dev": true, "requires": { - "js-base64": "2.4.2", + "js-base64": "2.4.3", "source-map": "0.4.4" }, "dependencies": { @@ -10358,9 +9600,9 @@ "dev": true }, "send": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", - "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", "dev": true, "requires": { "debug": "2.6.9", @@ -10370,12 +9612,12 @@ "escape-html": "1.0.3", "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", - "statuses": "1.3.1" + "statuses": "1.4.0" }, "dependencies": { "mime": { @@ -10383,12 +9625,6 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", "dev": true - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true } } }, @@ -10408,50 +9644,21 @@ "batch": "0.6.1", "debug": "2.6.9", "escape-html": "1.0.3", - "http-errors": "1.6.2", - "mime-types": "2.1.17", + "http-errors": "1.6.3", + "mime-types": "2.1.18", "parseurl": "1.3.2" - }, - "dependencies": { - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, - "requires": { - "mime-types": "2.1.18", - "negotiator": "0.6.1" - }, - "dependencies": { - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - } - } - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - } } }, "serve-static": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", - "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { "encodeurl": "1.0.2", "escape-html": "1.0.3", "parseurl": "1.3.2", - "send": "0.16.1" + "send": "0.16.2" } }, "set-blocking": { @@ -10494,31 +9701,21 @@ "dev": true }, "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, "sha.js": { - "version": "2.4.10", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz", - "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { "inherits": "2.0.3", "safe-buffer": "5.1.1" } }, - "shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", - "dev": true, - "requires": { - "json-stable-stringify": "0.0.1", - "sha.js": "2.4.10" - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -10534,18 +9731,6 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, - "shell-quote": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", - "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", - "dev": true, - "requires": { - "array-filter": "0.0.1", - "array-map": "0.0.0", - "array-reduce": "0.0.0", - "jsonify": "0.0.0" - } - }, "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", @@ -10723,7 +9908,76 @@ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, "requires": { - "hoek": "4.2.0" + "hoek": "4.2.1" + } + }, + "socket.io": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", + "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.4", + "socket.io-parser": "3.1.3" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", + "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.6.9", + "engine.io-client": "3.1.6", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "3.1.3", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", + "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "3.1.0", + "has-binary2": "1.0.2", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } } }, "sockjs": { @@ -10747,7 +10001,7 @@ "faye-websocket": "0.11.1", "inherits": "2.0.3", "json3": "3.3.2", - "url-parse": "1.2.0" + "url-parse": "1.4.0" }, "dependencies": { "faye-websocket": { @@ -10769,14 +10023,6 @@ "requires": { "ip": "1.1.5", "smart-buffer": "1.1.15" - }, - "dependencies": { - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - } } }, "socks-proxy-agent": { @@ -10788,6 +10034,24 @@ "agent-base": "2.1.1", "extend": "3.0.1", "socks": "1.1.10" + }, + "dependencies": { + "agent-base": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "dev": true, + "requires": { + "extend": "3.0.1", + "semver": "5.0.3" + } + }, + "semver": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", + "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", + "dev": true + } } }, "source-list-map": { @@ -10828,24 +10092,35 @@ "dev": true }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "spdy": { @@ -10859,22 +10134,22 @@ "http-deceiver": "1.2.7", "safe-buffer": "5.1.1", "select-hose": "2.0.0", - "spdy-transport": "2.0.20" + "spdy-transport": "2.1.0" } }, "spdy-transport": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz", - "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", + "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", "dev": true, "requires": { "debug": "2.6.9", "detect-node": "2.0.3", "hpack.js": "2.1.6", - "obuf": "1.1.1", + "obuf": "1.1.2", "readable-stream": "2.3.3", "safe-buffer": "5.1.1", - "wbuf": "1.7.2" + "wbuf": "1.7.3" } }, "split-string": { @@ -10908,9 +10183,9 @@ } }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { "asn1": "0.2.3", @@ -11026,27 +10301,6 @@ "readable-stream": "2.3.3" } }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "0.1.4", - "readable-stream": "2.3.3" - }, - "dependencies": { - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - } - } - }, "stream-consume": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", @@ -11054,9 +10308,9 @@ "dev": true }, "stream-http": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz", - "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", + "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", "dev": true, "requires": { "builtin-status-codes": "3.0.0", @@ -11066,16 +10320,6 @@ "xtend": "4.0.1" } }, - "stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", - "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3" - } - }, "stream-to": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stream-to/-/stream-to-0.2.2.tgz", @@ -11115,14 +10359,36 @@ } }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } } }, "string_decoder": { @@ -11182,13 +10448,13 @@ "integrity": "sha512-bLW0/lQxTgJ0y+TEllctly+/B0Hz2N82e5AhubP+FIVPSisyOzyFnZzWdqRml7RDwRCsT+EGNN8YYa0VFutT+w==", "dev": true, "requires": { - "buffer": "5.0.8", + "buffer": "5.1.0", "css-to-react-native": "2.1.2", "fbjs": "0.8.16", "hoist-non-react-statics": "1.2.0", "is-plain-object": "2.0.4", "prop-types": "15.6.1", - "stylis": "3.4.10", + "stylis": "3.5.0", "supports-color": "3.2.3" }, "dependencies": { @@ -11210,20 +10476,11 @@ } }, "stylis": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.4.10.tgz", - "integrity": "sha512-J7CXAfeyhjdgvdQMz2yy0gTDccq0nVmatx6IlX1je1kCqdNgk3npGOzX6qprEd2oHVv7IF5HXO08i6XFQs/JRA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.0.tgz", + "integrity": "sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw==", "dev": true }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "1.2.0" - } - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -11236,21 +10493,23 @@ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", "dev": true }, - "syntax-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", - "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", - "dev": true, - "requires": { - "acorn": "4.0.13" - } - }, "tapable": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", "dev": true }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, "temp": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", @@ -11281,12 +10540,6 @@ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, "through2": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", @@ -11332,20 +10585,12 @@ "dev": true }, "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", "dev": true, "requires": { - "process": "0.11.10" - }, - "dependencies": { - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - } + "setimmediate": "1.0.5" } }, "timespan": { @@ -11492,9 +10737,9 @@ } }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { "punycode": "1.4.1" @@ -11581,13 +10826,13 @@ } }, "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.17" + "mime-types": "2.1.18" } }, "typedarray": { @@ -11612,28 +10857,11 @@ "uglify-to-browserify": "1.0.2", "yargs": "3.10.0" }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", "dev": true }, "yargs": { @@ -11674,12 +10902,6 @@ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, - "umd": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", - "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", - "dev": true - }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -11776,6 +10998,23 @@ "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", "dev": true }, + "uri-js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", + "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "dev": true, + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + } + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -11801,19 +11040,19 @@ } }, "url-parse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", - "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.0.tgz", + "integrity": "sha512-ERuGxDiQ6Xw/agN4tuoCRbmwRuZP0cJ1lJxJubXr5Q/5cDa78+Dc4wfvtxzhzhkm5VvmW6Mf8EVj9SPGN4l8Lg==", "dev": true, "requires": { - "querystringify": "1.0.0", + "querystringify": "2.0.0", "requires-port": "1.0.0" }, "dependencies": { "querystringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", - "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", + "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", "dev": true } } @@ -11966,9 +11205,9 @@ "dev": true }, "uws": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/uws/-/uws-0.14.5.tgz", - "integrity": "sha1-Z6rzPEaypYel9mZtAPdpEyjxSdw=", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", + "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", "dev": true, "optional": true }, @@ -11982,13 +11221,13 @@ } }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "vary": { @@ -12140,85 +11379,23 @@ } }, "watchpack": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", - "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", "dev": true, "requires": { - "chokidar": "2.0.2", + "chokidar": "2.0.3", "graceful-fs": "4.1.11", - "neo-async": "2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "3.1.5", - "normalize-path": "2.1.1" - } - }, - "chokidar": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", - "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.0", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.4" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } - } - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } + "neo-async": "2.5.1" } }, "wbuf": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz", - "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "requires": { - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "webpack": { @@ -12227,11 +11404,11 @@ "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", "dev": true, "requires": { - "acorn": "5.5.0", + "acorn": "5.5.3", "acorn-dynamic-import": "2.0.2", - "ajv": "6.2.1", + "ajv": "6.4.0", "ajv-keywords": "3.1.0", - "async": "2.1.5", + "async": "2.6.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", "interpret": "1.1.0", @@ -12246,33 +11423,46 @@ "supports-color": "4.5.0", "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.5.0", + "watchpack": "1.6.0", "webpack-sources": "1.1.0", "yargs": "8.0.2" }, "dependencies": { - "acorn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.0.tgz", - "integrity": "sha512-arn53F07VXmls4o4pUhSzBa4fvaagPRe7AVZ8l7NHxFWUie2DsuFSBMMNAkgzRlOhEhzAnxeKyaWVzOH4xqp/g==", - "dev": true - }, "ajv": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.2.1.tgz", - "integrity": "sha1-KKarxJOiq+D7TIUHrK7bQ/pVBnE=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", + "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", "dev": true, "requires": { - "fast-deep-equal": "1.0.0", + "fast-deep-equal": "1.1.0", "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "json-schema-traverse": "0.3.1", + "uri-js": "3.0.2" } }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } }, "has-flag": { "version": "2.0.0", @@ -12280,12 +11470,6 @@ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -12298,17 +11482,6 @@ "strip-bom": "3.0.0" } }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -12354,25 +11527,6 @@ "read-pkg": "2.0.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - }, "supports-color": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", @@ -12382,12 +11536,6 @@ "has-flag": "2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "yargs": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", @@ -12450,12 +11598,12 @@ "ansi-html": "0.0.7", "array-includes": "3.0.3", "bonjour": "3.5.0", - "chokidar": "2.0.2", + "chokidar": "2.0.3", "compression": "1.7.2", "connect-history-api-fallback": "1.5.0", "debug": "3.1.0", "del": "3.0.0", - "express": "4.16.2", + "express": "4.16.3", "html-entities": "1.2.1", "http-proxy-middleware": "0.17.4", "import-local": "1.0.0", @@ -12463,7 +11611,7 @@ "ip": "1.1.5", "killable": "1.0.0", "loglevel": "1.6.1", - "opn": "5.2.0", + "opn": "5.3.0", "portfinder": "1.0.13", "selfsigned": "1.10.2", "serve-index": "1.9.1", @@ -12471,45 +11619,26 @@ "sockjs-client": "1.1.4", "spdy": "3.4.7", "strip-ansi": "3.0.1", - "supports-color": "5.3.0", + "supports-color": "5.4.0", "webpack-dev-middleware": "1.12.2", "yargs": "6.6.0" }, "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "3.1.5", - "normalize-path": "2.1.1" - } - }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, - "chokidar": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.2.tgz", - "integrity": "sha512-l32Hw3wqB0L2kGVmSbK/a+xXLDrUEsc84pSgMkmwygHvD7ubRsP/vxxHa5BtB6oix1XLLVCHyYMsckRXxThmZw==", + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.0", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.4" + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" } }, "debug": { @@ -12531,48 +11660,12 @@ "pinkie-promise": "2.0.1" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -12586,6 +11679,15 @@ "strip-bom": "2.0.0" } }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -12642,6 +11744,17 @@ "read-pkg": "1.1.0" } }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", @@ -12652,14 +11765,20 @@ } }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" } }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", @@ -12716,7 +11835,7 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": "0.4.10", + "http-parser-js": "0.4.12", "websocket-extensions": "0.1.3" } }, @@ -12727,9 +11846,9 @@ "dev": true }, "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", "dev": true }, "when": { @@ -12749,9 +11868,9 @@ } }, "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wide-align": { @@ -12761,6 +11880,19 @@ "dev": true, "requires": { "string-width": "1.0.2" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } } }, "window-size": { @@ -12770,9 +11902,9 @@ "dev": true }, "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", "dev": true }, "wrap-ansi": { @@ -12783,6 +11915,19 @@ "requires": { "string-width": "1.0.2", "strip-ansi": "3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } } }, "wrappy": { @@ -12792,11 +11937,13 @@ "dev": true }, "ws": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-2.0.3.tgz", - "integrity": "sha1-Uy/UmcP319cg5UPx+AcQbPxX2cs=", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", "ultron": "1.1.1" } }, @@ -12840,6 +11987,12 @@ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -12859,13 +12012,19 @@ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, "yargs": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.1.tgz", - "integrity": "sha512-7uRL1HZdCbc1QTP+X8mehOPuCYKC/XTaqAPj7gABLfTt6pgLyVRn3QVte4qhtilZouWCvqd1kipgMKl5tKsFiw==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.1.2.tgz", + "integrity": "sha512-ivSoxqBGYOqQVruxD35+EyCFDYNEFL/Uo6FcOnz+9xZdZzK0Zzw4r4KhbrME1Oo2gOggwJod2MnsdamSG7H9ig==", "dev": true, "requires": { - "cliui": "4.0.0", + "cliui": "4.1.0", "decamelize": "1.2.0", "find-up": "2.1.0", "get-caller-file": "1.0.2", @@ -12886,9 +12045,9 @@ "dev": true }, "cliui": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", - "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "2.1.1", @@ -12896,33 +12055,6 @@ "wrap-ansi": "2.1.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -12932,12 +12064,6 @@ "ansi-regex": "3.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "yargs-parser": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", @@ -12950,20 +12076,12 @@ } }, "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.0.0.tgz", + "integrity": "sha512-+DHejWujTVYeMHLff8U96rLc4uE4Emncoftvn5AjhB1Jw1pWxLzgBUT/WYbPrHmy6YPEBTZQx5myHhVcuuu64g==", "dev": true, "requires": { - "camelcase": "3.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - } + "camelcase": "4.1.0" } }, "yauzl": { diff --git a/uk.co.compucorp.civicrm.hrcore/package.json b/uk.co.compucorp.civicrm.hrcore/package.json index 29d22956599..af6426b3972 100644 --- a/uk.co.compucorp.civicrm.hrcore/package.json +++ b/uk.co.compucorp.civicrm.hrcore/package.json @@ -5,12 +5,12 @@ "backstop": "backstop" }, "devDependencies": { - "ansi-colors": "^1.0.1", - "backstopjs": "^3.1.19", + "ansi-colors": "^1.1.0", + "backstopjs": "^3.2.15", "civicrm-scssroot": "git://github.com/totten/civicrm-scssroot.git#v0.1.1", "detect-installed": "^2.0.4", - "es6-promise": "^4.2.2", - "find": "^0.2.8", + "es6-promise": "^4.2.4", + "find": "^0.2.9", "gulp": "^3.9.1", "gulp-clean": "^0.4.0", "gulp-color": "0.0.1", @@ -18,21 +18,21 @@ "gulp-notify": "^3.2.0", "gulp-rename": "^1.2.2", "gulp-replace": "^0.6.1", - "gulp-sass": "^3.1.0", + "gulp-sass": "^3.2.1", "gulp-sass-bulk-import": "^1.0.1", "gulp-sequence": "^1.0.0", "gulp-strip-css-comments": "^2.0.0", - "jasmine-core": "^2.9.1", - "karma": "^2.0.0", + "jasmine-core": "^2.99.1", + "karma": "^2.0.2", "karma-chrome-launcher": "^2.2.0", "karma-jasmine": "^1.1.1", "karma-junit-reporter": "^1.2.0", "karma-ng-html2js-preprocessor": "^1.0.0", "karma-requirejs": "^1.1.0", - "lodash": "^4.17.4", - "plugin-error": "^1.0.0", + "lodash": "^4.17.10", + "plugin-error": "^1.0.1", "requirejs": "^2.3.5", "xml-parse": "^0.3.1", - "yargs": "^10.1.1" + "yargs": "^10.1.2" } } diff --git a/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Files/sample_navigation_menu.json b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Files/sample_navigation_menu.json new file mode 100644 index 00000000000..fb427b924a7 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Files/sample_navigation_menu.json @@ -0,0 +1,212 @@ +{ + "1": { + "attributes": { + "label": "Home", + "name": "Home", + "url": "civicrm/tasksassignments/dashboard#/tasks", + "icon": null, + "permission": null, + "operator": "", + "separator": null, + "parentID": null, + "navID": "1", + "active": "1" + } + }, + "15": { + "attributes": { + "label": "Contacts", + "name": "Contacts", + "url": null, + "icon": "crm-i fa-users", + "permission": null, + "operator": "", + "separator": null, + "parentID": null, + "navID": "15", + "active": "1" + }, + "child": { + "18": { + "attributes": { + "label": "New Organization", + "name": "New Organization", + "url": "civicrm/contact/add?reset=1&ct=Organization", + "icon": null, + "permission": "add contacts", + "operator": "", + "separator": "1", + "parentID": "15", + "navID": "18", + "active": "1" + }, + "child": { + "265": { + "attributes": { + "label": "New Health Insurance Provider", + "name": "New Health_Insurance_Provider", + "url": "civicrm/contact/add?ct=Organization&cst=Health_Insurance_Provider&reset=1", + "icon": null, + "permission": "add contacts", + "operator": null, + "separator": "0", + "parentID": "18", + "navID": "265", + "active": "1" + } + } + } + } + } + }, + "110": { + "attributes": { + "label": "Administer", + "name": "Administer", + "url": null, + "icon": "crm-i fa-cog", + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": null, + "navID": "110", + "active": "1" + }, + "child": { + "111": { + "attributes": { + "label": "Administration Console", + "name": "Administration Console", + "url": "civicrm/admin?reset=1", + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "110", + "navID": "111", + "active": "1" + }, + "child": { + "112": { + "attributes": { + "label": "System Status", + "name": "System Status", + "url": "civicrm/a/#/status", + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "111", + "navID": "112", + "active": "1" + } + } + } + }, + "114": { + "attributes": { + "label": "Customize Data and Screens", + "name": "Customize Data and Screens", + "url": null, + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "110", + "navID": "114", + "active": "1" + }, + "child": { + "115": { + "attributes": { + "label": "Custom Fields", + "name": "Custom Fields", + "url": "civicrm/admin/custom/group?reset=1", + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "114", + "navID": "115", + "active": "1" + } + }, + "127": { + "attributes": { + "label": "Dropdown Options", + "name": "Dropdown Options", + "url": null, + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "114", + "navID": "127", + "active": "1" + }, + "child": { + "128": { + "attributes": { + "label": "Gender Options", + "name": "Gender Options", + "url": "civicrm/admin/options/gender?reset=1", + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "127", + "navID": "128", + "active": "1" + } + }, + "129": { + "attributes": { + "label": "Individual Prefixes (Ms, Mr...)", + "name": "Individual Prefixes (Ms, Mr...)", + "url": "civicrm/admin/options/individual_prefix?reset=1", + "icon": null, + "permission": "administer CiviCRM", + "operator": "", + "separator": null, + "parentID": "127", + "navID": "129", + "active": "1" + } + } + } + } + } + }, + "292": { + "attributes": { + "label": "Leave", + "name": "leave_and_absences", + "url": null, + "icon": null, + "permission": "administer leave and absences", + "operator": null, + "separator": null, + "parentID": "110", + "navID": "292", + "active": "1" + }, + "child": { + "293": { + "attributes": { + "label": "Leave/Absence Types", + "name": "leave_and_absence_types", + "url": "civicrm/admin/leaveandabsences/types?action=browse&reset=1", + "icon": null, + "permission": "administer leave and absences", + "operator": null, + "separator": "0", + "parentID": "292", + "navID": "293", + "active": "1" + } + } + } + } + } + } +} diff --git a/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Helper/NavigationMenuHelperTest.php b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Helper/NavigationMenuHelperTest.php new file mode 100644 index 00000000000..e81f3c01ddc --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Helper/NavigationMenuHelperTest.php @@ -0,0 +1,327 @@ +getSampleMenu(); + $result = NavigationMenuHelper::findMenuItemByPath($menu, $path); + $parts = explode('/', $path); + $expectedName = end($parts); + + if ($exists) { + $foundName = $result['attributes']['name']; + $this->assertEquals($expectedName, $foundName); + } + else { + $this->assertNull($result); + } + } + + public function testInsertionWillAddChildMenuItem() { + $menu = $this->getSampleMenu(); + $childName = 'Test Item'; + $attributes = ['foo' => 'bar']; + $parentName = 'Dropdown Options'; + $parentPath = 'Administer/Customize Data and Screens/' . $parentName; + $childPath = $parentPath . '/' . $childName; + NavigationMenuHelper::insert($menu, $childPath, $attributes); + + $added = NavigationMenuHelper::findMenuItemByPath($menu, $childPath); + $this->assertNotNull($added); + + $parentPath = NavigationMenuHelper::findMenuItemByPath($menu, $parentPath); + $children = $parentPath['child']; + $childMatches = array_filter($children, function ($item) use ($childName) { + return $item['attributes']['name'] === $childName; + }); + + $this->assertCount(1, $childMatches); + $matchingItem = reset($childMatches); + $this->assertEquals($childName, $matchingItem['attributes']['name']); + } + + public function testInsertionWillAddRootMenuItem() { + $menu = $this->getSampleMenu(); + $name = 'Foo'; + NavigationMenuHelper::insert($menu, $name); + $newestEntry = array_pop($menu); + + $this->assertEquals($name, $newestEntry['attributes']['name']); + } + + public function testAttributesWillOverrideDefaultsInInsertion() { + $menu = $this->getSampleMenu(); + $name = 'Foo'; + $label = 'Bar'; + NavigationMenuHelper::insert($menu, $name, ['label' => $label]); + $newestEntry = array_pop($menu); + + $this->assertEquals($label, $newestEntry['attributes']['label']); + } + + public function testInsertionWillThrowExceptionWithInvalidPath() { + $expectedError = 'Cannot find parent item "Foo"'; + $this->setExpectedException(\Exception::class, $expectedError); + $menu = []; + $path = 'Foo/Bar'; + NavigationMenuHelper::insert($menu, $path, []); + } + + public function testSettingPermissionWillUpdateItInMenu() { + $menu = $this->getSampleMenu(); + $path = 'Administer/Administration Console/System Status'; + NavigationMenuHelper::updatePermissionByPath($menu, $path, 'foo'); + $item = NavigationMenuHelper::findMenuItemByPath($menu, $path); + + $this->assertEquals('foo', $item['attributes']['permission']); + } + + public function testFindMenuItemByNameWillNotReturnAReference() { + $menu = $this->getSampleMenu(); + $name = 'Administer/Administration Console/System Status'; + $item = NavigationMenuHelper::findMenuItemByPath($menu, $name); + $item['foo'] = 'bar'; + $sameItem = NavigationMenuHelper::findMenuItemByPath($menu, $name); + + $this->assertArrayNotHasKey('foo', $sameItem); + } + + public function testMovingTopLevelMenuItemsWillChangeTheirPositions() { + $menu = $this->getSampleMenu(); + $first = 'Home'; + $second = 'Contacts'; + NavigationMenuHelper::relocateAfter($menu, $first, $second); + + $newFirst = reset($menu); + $newSecond = next($menu); + + $this->assertEquals($second, $newFirst['attributes']['name']); + $this->assertEquals($first, $newSecond['attributes']['name']); + } + + /** + * @dataProvider itemsToMoveProvider + * + * @param string $pathToMove + * @param string $pathBefore + */ + public function testInsertingAfterWillPlaceAfterNamedItem( + $pathToMove, + $pathBefore + ) { + $menu = $this->getSampleMenu(); + $parts = explode('/', $pathToMove); + $itemName = array_pop($parts); + $originalParentPath = implode('/', $parts); + $newParentParts = explode('/', $pathBefore); + $insertBeforeName = array_pop($newParentParts); + $newParentPath = implode('/', $newParentParts); + + NavigationMenuHelper::relocateAfter($menu, $pathToMove, $pathBefore); + + $matcherFunc = function ($child) use ($itemName) { + return $child['attributes']['name'] === $itemName; + }; + + if ($originalParentPath !== '') { + $originalParent = NavigationMenuHelper::findMenuItemByPath($menu, $originalParentPath); + $originalChildren = $originalParent['child']; + } else { + $originalChildren = $menu; + } + + if ($newParentPath !== '') { + $newParent = NavigationMenuHelper::findMenuItemByPath($menu, $newParentPath); + $newParentChildren = $newParent['child']; + } else { + $newParentChildren = $menu; + } + + // If it was moved to a different menu, check that it doesn't exist in old + if ($originalParentPath !== $newParentPath) { + $matchingOriginalChildren = array_filter($originalChildren, $matcherFunc); + $matchingNewChildren = array_filter($newParentChildren, $matcherFunc); + + $this->assertCount(0, $matchingOriginalChildren); + $this->assertCount(1, $matchingNewChildren); + } + + $moveTargetMenuNames = array_map(function ($item) { + return $item['attributes']['name']; + }, $newParentChildren); + + $moveBeforePosition = array_search($insertBeforeName, $moveTargetMenuNames); + $movedItemPosition = array_search($itemName, $moveTargetMenuNames); + $this->assertEquals($moveBeforePosition + 1, $movedItemPosition); + } + + /** + * @dataProvider itemsToMoveProvider + * + * @param string $pathToMove + * @param string $pathAfter + */ + public function testInsertingBeforeWillPlaceBeforeNamedItem( + $pathToMove, + $pathAfter + ) { + $menu = $this->getSampleMenu(); + $parts = explode('/', $pathToMove); + $itemName = array_pop($parts); + $originalParentPath = implode('/', $parts); + $newParentParts = explode('/', $pathAfter); + $insertBeforeName = array_pop($newParentParts); + $newParentPath = implode('/', $newParentParts); + + NavigationMenuHelper::relocateBefore($menu, $pathToMove, $pathAfter); + + $matcherFunc = function ($child) use ($itemName) { + return $child['attributes']['name'] === $itemName; + }; + + if ($originalParentPath !== '') { + $originalParent = NavigationMenuHelper::findMenuItemByPath($menu, $originalParentPath); + $originalChildren = $originalParent['child']; + } else { + $originalChildren = $menu; + } + + if ($newParentPath !== '') { + $newParent = NavigationMenuHelper::findMenuItemByPath($menu, $newParentPath); + $newParentChildren = $newParent['child']; + } else { + $newParentChildren = $menu; + } + + // If it was moved to a different menu, check that it doesn't exist in old + if ($originalParentPath !== $newParentPath) { + $matchingOriginalChildren = array_filter($originalChildren, $matcherFunc); + $matchingNewChildren = array_filter($newParentChildren, $matcherFunc); + + $this->assertCount(0, $matchingOriginalChildren); + $this->assertCount(1, $matchingNewChildren); + } + + $moveTargetMenuNames = array_map(function ($item) { + return $item['attributes']['name']; + }, $newParentChildren); + + $moveBeforePosition = array_search($insertBeforeName, $moveTargetMenuNames); + $movedItemPosition = array_search($itemName, $moveTargetMenuNames); + $this->assertEquals($moveBeforePosition - 1, $movedItemPosition); + } + + public function testRemovalWillUnsetElementAndChildren() { + $menu = $this->getSampleMenu(); + $rootElement = 'Administer'; + $childElement = 'Administer/Custom Fields'; + NavigationMenuHelper::remove($menu, $rootElement); + + $foundRoot = NavigationMenuHelper::findMenuItemByPath($menu, $rootElement); + $foundChild = NavigationMenuHelper::findMenuItemByPath($menu, $childElement); + $this->assertNull($foundRoot); + $this->assertNull($foundChild); + } + + public function menuItemParentNameProvider() { + return [ + [ + 'Home', + 'root' + ], + [ + 'ta_dashboard_tasks', + 'tasksassignments' + ], + [ + 'hrjc_revision_change_reason', + 'Dropdown Options' + ], + [ + 'I_DO_NOT_EXIST', + NULL + ], + [ + 'Administer', + 'root' + ] + ]; + } + + /** + * @return array + */ + public function menuItemNameProvider() { + return [ + [ + 'Home', + TRUE + ], + [ + 'I_DO_NOT_EXIST', + FALSE + ], + [ + 'Contacts/New Organization/New Health_Insurance_Provider', + TRUE + ], + [ + 'Administer/Administration Console', + TRUE + ], + [ + 'Administer/Customize Data and Screens/Dropdown Options/Gender Options', + TRUE + ] + ]; + } + + /** + * @return array + */ + public function itemsToMoveProvider() { + return [ + [ + 'Administer/Administration Console', + 'Home' + ], + [ + 'Home', + 'Administer' + ], + [ + 'Administer/Customize Data and Screens/Custom Fields', + 'Contacts/New Organization' + ], + [ + 'Administer/Customize Data and Screens/Dropdown Options/Gender Options', + 'Administer/Administration Console', + ] + ]; + } + + /** + * Get a sample navigation menu array + * + * @return array + */ + private function getSampleMenu() { + $jsonFile = __DIR__ . '/../Files/sample_navigation_menu.json'; + $contents = file_get_contents($jsonFile); + + return json_decode($contents, TRUE); + } + +} diff --git a/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Hook/BuildForm/OptionEditPathFilterTest.php b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Hook/BuildForm/OptionEditPathFilterTest.php new file mode 100644 index 00000000000..da1c11900ec --- /dev/null +++ b/uk.co.compucorp.civicrm.hrcore/tests/phpunit/CRM/HRCore/Hook/BuildForm/OptionEditPathFilterTest.php @@ -0,0 +1,55 @@ +add('text', 'bar'); + $cloneElement = clone $element; + $original->addElement($cloneElement); + + $filter->handle('TestForm', $form); + + $this->assertEquals($original, $form); + } + + public function testOptionEditPathWillNotBeRemovedIfNotLocked() { + civicrm_api3('OptionGroup', 'create', ['name' => 'foo']); + + $filter = new OptionEditPathFilter(); + $form = new CRM_Contact_Form_Contact(); + + $element = $form->add('text', 'bar'); + $editPath = 'civicrm/admin/options/foo'; + $attrKey = 'data-option-edit-path'; + $element->setAttribute($attrKey, $editPath); + + $filter->handle('TestForm', $form); + + $this->assertEquals($editPath, $element->getAttribute($attrKey)); + } + + public function testOptionEditPathWillBeRemovedIfLocked() { + civicrm_api3('OptionGroup', 'create', ['name' => 'bar', 'is_locked' => 1]); + + $filter = new OptionEditPathFilter(); + $form = new CRM_Contact_Form_Contact(); + $element = $form->add('text', 'bar'); + $attrKey = 'data-option-edit-path'; + $element->setAttribute($attrKey, 'civicrm/admin/options/bar'); + + $filter->handle('TestForm', $form); + + $this->assertNull($element->getAttribute($attrKey)); + } + +} diff --git a/uk.co.compucorp.civicrm.hremails/info.xml b/uk.co.compucorp.civicrm.hremails/info.xml index f2f1b5cbb30..e2b4e4cc502 100644 --- a/uk.co.compucorp.civicrm.hremails/info.xml +++ b/uk.co.compucorp.civicrm.hremails/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/uk.co.compucorp.civicrm.hremails/package-lock.json b/uk.co.compucorp.civicrm.hremails/package-lock.json index 67360e959a5..0ac8d71ecee 100644 --- a/uk.co.compucorp.civicrm.hremails/package-lock.json +++ b/uk.co.compucorp.civicrm.hremails/package-lock.json @@ -122,6 +122,14 @@ "dev": true, "requires": { "hoek": "4.2.1" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } } }, "bower": { @@ -244,6 +252,14 @@ "dev": true, "requires": { "hoek": "4.2.1" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } } } } @@ -535,14 +551,16 @@ "cryptiles": "3.1.2", "hoek": "4.2.1", "sntp": "2.1.0" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } } }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2750,6 +2768,14 @@ "dev": true, "requires": { "hoek": "4.2.1" + }, + "dependencies": { + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + } } }, "sprintf-js": { diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDates.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDates.php index 36bade50a0b..42efac49fa1 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDates.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDates.php @@ -63,20 +63,48 @@ private function canHandleTheRequest($apiRequest) { */ private function prepareDates(&$apiRequest) { $params = &$apiRequest['params']; + $this->adjustTimeOnDates($params, 'from_date', '00:00:00'); + $this->adjustTimeOnDates($params, 'to_date', '23:59:59'); + } - $fromDate = $this->getValueFromParams($params, 'from_date'); - - if ($this->dateIsValid($fromDate) && $this->dateIsMissingHours($fromDate)) { - $fromDate = (new DateTime($fromDate))->format('Y-m-d 00:00:00'); - $this->setValueOfParam($params, 'from_date', $fromDate); + /** + * Sets the time on date(s) of a certain parameter value to the provided + * time if they do not already have the time specified + * + * @param array $params + * @param string $paramKey + * @param string $time + */ + private function adjustTimeOnDates(&$params, $paramKey, $time) { + $dates = $this->getValueFromParams($params, $paramKey); + + if (is_array($dates)) { + foreach ($dates as $key => $date) { + $dates[$key] = $this->setTimeForDate($date, $time); + } + $this->setValueOfParam($params, $paramKey, $dates); } + else { + $date = $this->setTimeForDate($dates, $time); + $this->setValueOfParam($params, $paramKey, $date); + } + } - $toDate = $this->getValueFromParams($params, 'to_date'); - - if ($this->dateIsValid($toDate) && $this->dateIsMissingHours($toDate)) { - $toDate = (new DateTime($toDate))->format('Y-m-d 23:59:59'); - $this->setValueOfParam($params, 'to_date', $toDate); + /** + * Returns the date with the time set to the value provided, but only if it + * doesn't already have time set and it is a valid date + * + * @param string $date + * @param string $time + * + * @return string + */ + private function setTimeForDate($date, $time) { + if ($this->dateIsValid($date) && $this->dateIsMissingHours($date)) { + return (new DateTime($date))->format('Y-m-d ' . $time); } + + return $date; } /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChange.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChange.php index fee1f0f7d8a..5a67592f88d 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChange.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChange.php @@ -8,6 +8,7 @@ use CRM_Hrjobcontract_BAO_HRJobContractRevision as HRJobContractRevision; use CRM_Hrjobcontract_BAO_HRJobDetails as HRJobDetails; use CRM_HRLeaveAndAbsences_Service_LeaveDateAmountDeduction as LeaveDateAmountDeduction; +use CRM_HRLeaveAndAbsences_BAO_LeaveBalanceChangeExpiryLog as LeaveBalanceChangeExpiryLog; class CRM_HRLeaveAndAbsences_BAO_LeaveBalanceChange extends CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChange { @@ -752,15 +753,17 @@ private static function getBalanceChangesToExpire() { LEFT JOIN {$absencePeriodTable} absence_period ON period_entitlement.period_id = absence_period.id WHERE balance_to_expire.expiry_date IS NOT NULL AND - balance_to_expire.expiry_date < CURDATE() AND + balance_to_expire.expiry_date < %3 AND balance_to_expire.expired_balance_change_id IS NULL AND - expired_balance_change.id IS NULL + expired_balance_change.id IS NULL AND + coalesce(leave_request.type_id, period_entitlement.type_id) IS NOT NULL ORDER BY balance_to_expire.expiry_date ASC, balance_to_expire.id ASC "; $params = [ 1 => [self::SOURCE_LEAVE_REQUEST_DAY, 'String'], 2 => [self::SOURCE_ENTITLEMENT, 'String'], + 3 => [date('Y-m-d'), 'String'] ]; $result = CRM_Core_DAO::executeQuery($query, $params); @@ -1029,7 +1032,8 @@ private static function calculateExpiryAmount($balanceChanges, $datesOverlapping $params['id'] = $expiryBalanceChange->id; } - self::create($params); + $balanceChange = self::create($params); + self::logExpiredBalanceChange($balanceChange); $numberOfRecords++; } @@ -1037,6 +1041,30 @@ private static function calculateExpiryAmount($balanceChanges, $datesOverlapping return $numberOfRecords; } + /** + * Logs the expired balance change using the LeaveBalanceChangeExpiryLog entity. + * + * @param \CRM_HRLeaveAndAbsences_BAO_LeaveBalanceChange $expiredBalanceChange + */ + private static function logExpiredBalanceChange($expiredBalanceChange) { + $logData = [ + 'balance_change_id' => $expiredBalanceChange->id, + 'source_id' => $expiredBalanceChange->source_id, + 'source_type' => $expiredBalanceChange->source_type, + 'expiry_date' => CRM_Utils_Date::processDate($expiredBalanceChange->expiry_date), + 'balance_type_id' => $expiredBalanceChange->type_id, + 'amount' => $expiredBalanceChange->amount, + ]; + + if ($expiredBalanceChange->source_type == self::SOURCE_LEAVE_REQUEST_DAY) { + $leaveDate = LeaveRequestDate::findById($expiredBalanceChange->source_id); + $logData['leave_date'] = CRM_Utils_Date::processDate($leaveDate->date); + $logData['leave_request_id'] = $leaveDate->leave_request_id; + } + + LeaveBalanceChangeExpiryLog::create($logData); + } + /** * Returns the current balance (i.e. not including balance changes caused by * open leave requests) for the given Contacts during the given Absence Period. diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLog.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLog.php new file mode 100644 index 00000000000..e5b11ec46c1 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLog.php @@ -0,0 +1,94 @@ +copyValues($params); + $instance->save(); + CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance); + + return $instance; + } + + /** + * A method for validating the params passed to the + * LeaveBalanceChangeExpiryLog create method + * + * @param array $params + * The params array received by the create method + * + * @throws InvalidLeaveBalanceChangeExpiryLogException + */ + public static function validateParams($params) { + self::validateUpdatesNotAllowed($params); + self::validateMandatory($params); + } + + /** + * A method for validating the mandatory fields in the params + * passed to the LeaveBalanceChangeExpiryLog create method + * + * @param array $params + * The params array received by the create method + * + * @throws InvalidLeaveBalanceChangeExpiryLogException + */ + private static function validateMandatory($params) { + $mandatoryFields = [ + 'balance_change_id', + 'source_id', + 'source_type', + 'expiry_date', + 'balance_type_id' + ]; + + foreach($mandatoryFields as $field) { + if (empty($params[$field])) { + throw new InvalidLeaveBalanceChangeExpiryLogException( + "The {$field} field should not be empty" + ); + } + } + + if(!isset($params['amount'])) { + throw new InvalidLeaveBalanceChangeExpiryLogException( + 'The amount field should not be empty' + ); + } + } + + /** + * A method for validating that updates are not allowed + * for the LeaveBalanceChangeExpiryLog Entity. Since it is + * for logging purposes, we don't want the records to be + * manipulated or updated + * + * @param array $params + * The params array received by the create method + * + * @throws InvalidLeaveBalanceChangeExpiryLogException + */ + private static function validateUpdatesNotAllowed($params) { + if(!empty($params['id'])) { + throw new InvalidLeaveBalanceChangeExpiryLogException( + 'Updates not allowed for the LeaveBalanceChange Expiry Log entity' + ); + } + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveRequest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveRequest.php index 03d7da1b001..83a46c6be63 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveRequest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/BAO/LeaveRequest.php @@ -332,12 +332,10 @@ private static function validateTOILToAccrueIsAValidOptionValue($params, $absenc * @throws \CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException */ private static function validateTOILPastDays($params, $absenceType) { - $fromDate = new DateTime($params['from_date']); - $toDate = new DateTime($params['to_date']); - $todayDate = new DateTime('today'); - $leaveDatesHasPastDates = $fromDate < $todayDate || $toDate < $todayDate; + $leaveDatesHasPastDates = self::isTOILWithPastDates($params); + $isACancellationRequest = in_array($params['status_id'], LeaveRequest::getCancelledStatuses()); - if ($leaveDatesHasPastDates && !$absenceType->allow_accrue_in_the_past) { + if ($leaveDatesHasPastDates && !$absenceType->allow_accrue_in_the_past && !$isACancellationRequest) { throw new InvalidLeaveRequestException( 'You may only request TOIL for overtime to be worked in the future. Please modify the date of this request', 'leave_request_toil_cannot_be_requested_for_past_days', @@ -346,6 +344,26 @@ private static function validateTOILPastDays($params, $absenceType) { } } + /** + * Checks whether the leave request is of type TOIL and has dates in the + * past. + * + * @param array $params + * + * @return bool + */ + public static function isTOILWithPastDates($params) { + if($params['request_type'] !== LeaveRequest::REQUEST_TYPE_TOIL) { + return FALSE; + } + + $fromDate = new DateTime($params['from_date']); + $toDate = new DateTime($params['to_date']); + $todayDate = new DateTime('today'); + + return $fromDate < $todayDate || $toDate < $todayDate; + } + /** * Validate that the TOIL amount to be accrued plus total approved accrued TOIL for the period * is not greater than the maximum defined(if any) for the Absence Type @@ -645,9 +663,7 @@ private static function validateNoOverlappingLeaveRequests($params) { ]; $overlappingLeaveRequests = self::findOverlappingLeaveRequests( - $params['contact_id'], - $params['from_date'], - $params['to_date'], + $params, $leaveRequestStatusFilter ); @@ -843,22 +859,101 @@ public static function findPublicHolidayLeaveRequestEvenIfDeleted($contactID, Pu } /** - * Returns the leave request days already existing for the given contact - * within the $fromDate to $todDate period and having the statuses supplied. + * Returns existing leave requests considered "overlapping" + * for the given leave request parameters and statuses supplied. * - * @param int $contactID - * @param string $fromDate - * @param string $toDate + * @param array $leaveRequestParams + * List of parameters to use to create the Case. + * [ + * 'contact_id' => int, + * 'type_id' => int, + * 'request_type' => int, + * 'from_date' => string, + * 'from_date_type' => string|int optional, + * 'to_date' => string, + * 'to_date_type' => string|int optional + * ] * @param array $leaveRequestStatus * @param boolean $excludePublicHolidayLeaveRequests * Whether to exclude public holiday leave requests from overlapping leave requests or not * * @return \CRM_HRLeaveAndAbsences_BAO_LeaveRequest[]|null */ - public static function findOverlappingLeaveRequests($contactID, $fromDate, $toDate, $leaveRequestStatus = [], $excludePublicHolidayLeaveRequests = true) { + public static function findOverlappingLeaveRequests($leaveRequestParams, $leaveRequestStatus = [], $excludePublicHolidayLeaveRequests = TRUE) { + $fromDateObj = new DateTime($leaveRequestParams['from_date']); + $fromDate = $fromDateObj->format('Y-m-d'); + $fromDateTime = $fromDateObj->format('Y-m-d H:i:s'); + $fromDateType = isset($leaveRequestParams['from_date_type']) ? (int)$leaveRequestParams['from_date_type'] : NULL; + $toDateObj = new DateTime($leaveRequestParams['to_date']); + $toDate = $toDateObj->format('Y-m-d'); + $toDateTime = $toDateObj->format('Y-m-d H:i:s'); + $toDateType = isset($leaveRequestParams['to_date_type']) ? (int)$leaveRequestParams['to_date_type'] : NULL; + $leaveRequestTable = self::getTableName(); $leaveRequestDateTable = LeaveRequestDate::getTableName(); $leaveBalanceChangeTable = LeaveBalanceChange::getTableName(); + $leaveRequestAbsenceType = AbsenceType::findById($leaveRequestParams['type_id']); + $isCalculationUnitInHours = $leaveRequestAbsenceType->isCalculationUnitInHours(); + $absenceTypes = AbsenceType::getEnabledAbsenceTypes(); + $absenceTypesIDs = []; + $absenceTypesIDsWithSameUnit = []; + $absenceTypesIDsWithDifferentUnit = []; + $leaveRequestDayTypes = array_flip(self::buildOptions('from_date_type', 'validate')); + $halfDayAMID = $leaveRequestDayTypes['half_day_am']; + $halfDayPMID = $leaveRequestDayTypes['half_day_pm']; + $toilType = LeaveRequest::REQUEST_TYPE_TOIL; + $isTOIL = $leaveRequestParams['request_type'] === $toilType; + $isCalculationUnitInHoursOrTOIL = $isCalculationUnitInHours || $isTOIL; + $absenceTypesSelector = ''; + $considerRequestsInDifferentUnit = ''; + $ignoreHalfDayRequests = ''; + + foreach ($absenceTypes as $absenceType) { + $absenceTypesIDs[] = $absenceType->id; + if ($leaveRequestAbsenceType->calculation_unit === $absenceType->calculation_unit) { + $absenceTypesIDsWithSameUnit[] = $absenceType->id; + } else { + $absenceTypesIDsWithDifferentUnit[] = $absenceType->id; + } + } + + $sameUnitSelector = 'lr.type_id IN (' . implode(',', $absenceTypesIDsWithSameUnit) . ')'; + + $dateTimeSelector = $isCalculationUnitInHoursOrTOIL + ? "lr.from_date < '{$toDateTime}' AND lr.to_date > '{$fromDateTime}'" + : "lrd.date BETWEEN '{$fromDate}' AND '{$toDate}'"; + + if (!$isTOIL) { + if ($isCalculationUnitInHours) { + $absenceTypesSelector = 'AND ' . $sameUnitSelector; + + if (count($absenceTypesIDsWithDifferentUnit)) { + $considerRequestsInDifferentUnit = + "OR ((lrd.date BETWEEN '{$fromDate}' AND '{$toDate}') AND lr.type_id IN (" . + implode(',', $absenceTypesIDsWithDifferentUnit) . "))"; + } + } else { + $absenceTypesSelector = 'AND lr.type_id IN (' . implode(',', $absenceTypesIDs) . ')'; + } + } + + if (!$isCalculationUnitInHoursOrTOIL && count($absenceTypesIDsWithSameUnit)) { + $ignoreHalfDayRequests = + ($fromDateType === $halfDayPMID + ? "AND NOT(DATE_FORMAT(lr.to_date, '%Y-%m-%d') = '{$fromDate}' " . + "AND lr.to_date_type = {$halfDayAMID} AND {$sameUnitSelector})" + : "") . + ($toDateType === $halfDayAMID + ? "AND NOT(DATE_FORMAT(lr.from_date, '%Y-%m-%d') = '{$toDate}' " . + "AND lr.from_date_type = {$halfDayPMID} AND {$sameUnitSelector})" + : ""); + } + + $overlapSelector = + "($dateTimeSelector $absenceTypesSelector $considerRequestsInDifferentUnit) $ignoreHalfDayRequests"; + + $ignoreRequestTypes = + 'lr.request_type ' . ($isTOIL ? '=' : '!=') . "'" . $toilType . "'"; $query = " SELECT DISTINCT lr.* FROM {$leaveRequestTable} lr @@ -866,9 +961,8 @@ public static function findOverlappingLeaveRequests($contactID, $fromDate, $toDa ON lrd.leave_request_id = lr.id INNER JOIN {$leaveBalanceChangeTable} lbc ON lbc.source_id = lrd.id AND lbc.source_type = %1 - WHERE lr.contact_id = %2 AND lr.is_deleted = 0 - AND lrd.date BETWEEN %3 AND %4 - "; + WHERE lr.contact_id = %2 AND lr.is_deleted = 0 AND ({$overlapSelector}) + AND {$ignoreRequestTypes}"; if (is_array($leaveRequestStatus) && !empty($leaveRequestStatus)) { array_walk($leaveRequestStatus, 'intval'); @@ -876,15 +970,13 @@ public static function findOverlappingLeaveRequests($contactID, $fromDate, $toDa } if ($excludePublicHolidayLeaveRequests) { - $query .= " AND lr.request_type != %5"; + $query .= " AND lr.request_type != %3"; } $params = [ 1 => [LeaveBalanceChange::SOURCE_LEAVE_REQUEST_DAY, 'String'], - 2 => [$contactID, 'Integer'], - 3 => [CRM_Utils_Date::processDate($fromDate, null, false, 'Y-m-d'), 'String'], - 4 => [CRM_Utils_Date::processDate($toDate, null, false, 'Y-m-d'), 'String'], - 5 => [self::REQUEST_TYPE_PUBLIC_HOLIDAY, 'String'] + 2 => [$leaveRequestParams['contact_id'], 'Integer'], + 3 => [self::REQUEST_TYPE_PUBLIC_HOLIDAY, 'String'] ]; $leaveRequest = CRM_Core_DAO::executeQuery($query, $params, true, self::class); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/ContactWorkPattern.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/ContactWorkPattern.php index fd25c5fe6e2..5c0a0e1be47 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/ContactWorkPattern.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/ContactWorkPattern.php @@ -30,7 +30,7 @@ * * Generated from xml/schema/CRM/HRLeaveAndAbsences/ContactWorkPattern.xml * DO NOT EDIT. Generated by CRM_Core_CodeGen - * (GenCodeChecksum:dd2637660ac3be9bdaeb2955643974ae) + * (GenCodeChecksum:ded89fd6039ec891ba28b56d418a3179) */ require_once 'CRM/Core/DAO.php'; require_once 'CRM/Utils/Type.php'; @@ -181,8 +181,8 @@ static function &fields() { 'bao' => 'CRM_HRLeaveAndAbsences_DAO_ContactWorkPattern', 'localizable' => 0, 'pseudoconstant' => array( - 'optionGroupName' => 'hrjc_revision_change_reason', - 'optionEditPath' => 'civicrm/admin/options/hrjc_revision_change_reason', + 'optionGroupName' => 'hrleaveandabsences_work_pattern_change_reason', + 'optionEditPath' => 'civicrm/admin/options/hrleaveandabsences_work_pattern_change_reason', ) ) , ); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/LeaveBalanceChangeExpiryLog.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/LeaveBalanceChangeExpiryLog.php new file mode 100644 index 00000000000..f3661b6a4b5 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/DAO/LeaveBalanceChangeExpiryLog.php @@ -0,0 +1,302 @@ +__table = 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log'; + parent::__construct(); + } + /** + * Returns all the column names of this table + * + * @return array + */ + static function &fields() { + if (!isset(Civi::$statics[__CLASS__]['fields'])) { + Civi::$statics[__CLASS__]['fields'] = array( + 'id' => array( + 'name' => 'id', + 'type' => CRM_Utils_Type::T_INT, + 'description' => 'Unique LeaveBalanceChangeExpiryLog ID', + 'required' => true, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'balance_change_id' => array( + 'name' => 'balance_change_id', + 'type' => CRM_Utils_Type::T_INT, + 'description' => 'The expired balance change ID', + 'required' => true, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'amount' => array( + 'name' => 'amount', + 'type' => CRM_Utils_Type::T_MONEY, + 'title' => ts('Amount') , + 'description' => 'The expired balance amount', + 'required' => true, + 'precision' => array( + 20, + 2 + ) , + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'source_id' => array( + 'name' => 'source_id', + 'type' => CRM_Utils_Type::T_INT, + 'description' => 'Expired Balance change source ID', + 'required' => true, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'source_type' => array( + 'name' => 'source_type', + 'type' => CRM_Utils_Type::T_STRING, + 'title' => ts('Source Type') , + 'description' => 'Expired Balance change source type', + 'required' => true, + 'maxlength' => 20, + 'size' => CRM_Utils_Type::MEDIUM, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'expiry_date' => array( + 'name' => 'expiry_date', + 'type' => CRM_Utils_Type::T_DATE, + 'title' => ts('Expiry Date') , + 'description' => 'The balance change expiry date', + 'required' => true, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'balance_type_id' => array( + 'name' => 'balance_type_id', + 'type' => CRM_Utils_Type::T_INT, + 'description' => 'One of the values of the Leave Balance Type option group', + 'required' => true, + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + 'pseudoconstant' => array( + 'optionGroupName' => 'hrleaveandabsences_leave_balance_change_type', + 'optionEditPath' => 'civicrm/admin/options/hrleaveandabsences_leave_balance_change_type', + ) + ) , + 'leave_date' => array( + 'name' => 'leave_date', + 'type' => CRM_Utils_Type::T_DATE, + 'title' => ts('Leave Date') , + 'description' => 'The Leave date of the expired balance change (i.e If it is a leave request balance change)', + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'leave_request_id' => array( + 'name' => 'leave_request_id', + 'type' => CRM_Utils_Type::T_INT, + 'description' => 'The Leave Request ID linked to the expired balance change (i.e If it is a leave request balance change)', + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + 'created_date' => array( + 'name' => 'created_date', + 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME, + 'title' => ts('Created Date') , + 'description' => 'The date and time this log was created', + 'table_name' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + 'entity' => 'LeaveBalanceChangeExpiryLog', + 'bao' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'localizable' => 0, + ) , + ); + CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']); + } + return Civi::$statics[__CLASS__]['fields']; + } + /** + * Return a mapping from field-name to the corresponding key (as used in fields()). + * + * @return array + * Array(string $name => string $uniqueName). + */ + static function &fieldKeys() { + if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) { + Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields())); + } + return Civi::$statics[__CLASS__]['fieldKeys']; + } + /** + * Returns the names of this table + * + * @return string + */ + static function getTableName() { + return self::$_tableName; + } + /** + * Returns if this table needs to be logged + * + * @return boolean + */ + function getLog() { + return self::$_log; + } + /** + * Returns the list of fields that can be imported + * + * @param bool $prefix + * + * @return array + */ + static function &import($prefix = false) { + $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'hrleaveandabsences_leave_balance_change_expiry_log', $prefix, array()); + return $r; + } + /** + * Returns the list of fields that can be exported + * + * @param bool $prefix + * + * @return array + */ + static function &export($prefix = false) { + $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'hrleaveandabsences_leave_balance_change_expiry_log', $prefix, array()); + return $r; + } + /** + * Returns the list of indices + */ + public static function indices($localize = TRUE) { + $indices = array(); + return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Exception/InvalidLeaveBalanceChangeExpiryLogException.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Exception/InvalidLeaveBalanceChangeExpiryLogException.php new file mode 100644 index 00000000000..8e425629ede --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Exception/InvalidLeaveBalanceChangeExpiryLogException.php @@ -0,0 +1,2 @@ +leaveRequest->contact_id]; $allRecipients = array_merge($leaveApprovers, $leaveContact); + $loggedInContactID = CRM_Core_Session::getLoggedInContactID(); + $currentContactKey = array_search($loggedInContactID, $allRecipients); + + if ($currentContactKey !== FALSE) { + unset($allRecipients[$currentContactKey]); + } $result = civicrm_api3('Email', 'get', [ 'contact_id' => ['IN' => $allRecipients], @@ -179,7 +185,7 @@ public function getRecipientEmails() { */ private function getLeaveApprovers() { $leaveApprovers = $this->leaveManagerService->getLeaveApproversForContact($this->leaveRequest->contact_id); - + return array_keys($leaveApprovers); } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequest.php index 460d668c606..6144107da4a 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequest.php @@ -117,6 +117,16 @@ protected function update($params) { ); } + $isTOILWithPastDates = LeaveRequest::isTOILWithPastDates($params); + $isCancelledStatus = $this->isCancelledStatus($params); + $canCanCancelTOILWithPastDates = $this->canCanCancelTOILWithPastDates($params); + + if ($isTOILWithPastDates && $isCancelledStatus && !$canCanCancelTOILWithPastDates) { + throw new RuntimeException( + 'You may only cancel TOIL with dates in the future.' + ); + } + return $this->createRequestWithBalanceChanges($params); } @@ -375,4 +385,29 @@ private function skipBalanceChangeUpdate($params) { return ($leaveRequestDatesNotChanged || $toilDatesAndToAccrueNotChanged) && !$updateBalanceChange; } + + /** + * Checks If the current user can cancel a TOIL request type that has past dates. + * + * @param array $params + * + * @return bool + */ + private function canCanCancelTOILWithPastDates($params) { + return $this->leaveRequestRightsService->canCancelToilWithPastDates( + $params['contact_id'], + $params['type_id'] + ); + } + + /** + * Checks whether the Leave is to be updated to cancelled. + * + * @param array $params + * + * @return bool + */ + private function isCancelledStatus($params) { + return in_array($params['status_id'], LeaveRequest::getCancelledStatuses()); + } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequestRights.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequestRights.php index fa12252589c..c392b880d7b 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequestRights.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Service/LeaveRequestRights.php @@ -2,6 +2,7 @@ use CRM_HRLeaveAndAbsences_Service_LeaveManager as LeaveManagerService; use CRM_HRLeaveAndAbsences_BAO_LeaveRequest as LeaveRequest; +use CRM_HRLeaveAndAbsences_BAO_AbsenceType as AbsenceType; class CRM_HRLeaveAndAbsences_Service_LeaveRequestRights { @@ -151,4 +152,25 @@ private static function getLeaveRequestStatuses() { return self::$leaveStatuses; } + + /** + * Checks whether the current user can cancel the TOIL Request with + * past dates or not. + * + * @param int $contactID + * The contactID of the leave request + * @param int $absenceTypeID + * The absence Type ID of the leave request + * + * @return bool + */ + public function canCancelToilWithPastDates($contactID, $absenceTypeID) { + $absenceType = AbsenceType::findById($absenceTypeID); + + if(!$absenceType->allow_accrue_in_the_past) { + return $this->currentUserIsManagerOrAdmin($contactID); + } + + return TRUE; + } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Test/Fabricator/LeaveRequest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Test/Fabricator/LeaveRequest.php index 0623d4a13bc..3ef7ff16cd7 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Test/Fabricator/LeaveRequest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Test/Fabricator/LeaveRequest.php @@ -1,5 +1,6 @@ isCalculationUnitInHours(); + $isTOIL = isset($params['request_type']) && $params['request_type'] === LeaveRequest::REQUEST_TYPE_TOIL; + $defaultParams = [ + 'type_id' => $absenceType->id, 'status_id' => self::getStatusId('approved'), - 'from_date_type' => self::getDayTypeId('all_day'), 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE ]; - if(!empty($params['to_date']) && empty($params['to_date_type'])) { - $defaultParams['to_date_type'] = self::getDayTypeId('all_day'); + if (!$isCalculationUnitInHours) { + $defaultParams['from_date_type'] = self::getDayTypeId('all_day'); + + if (!empty($params['to_date']) && empty($params['to_date_type'])) { + $defaultParams['to_date_type'] = self::getDayTypeId('all_day'); + } + } else { + $defaultParams['from_date_amount'] = 1; + $defaultParams['to_date_amount'] = 1; + } + + if ($isTOIL) { + $defaultParams['toil_duration'] = 1; + $defaultParams['toil_to_accrue'] = 1; } return array_merge($defaultParams, $params); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader.php index fd996daf1bf..6a123c158c9 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader.php @@ -26,6 +26,14 @@ class CRM_HRLeaveAndAbsences_Upgrader extends CRM_HRLeaveAndAbsences_Upgrader_Ba use CRM_HRLeaveAndAbsences_Upgrader_Step_1018; use CRM_HRLeaveAndAbsences_Upgrader_Step_1019; use CRM_HRLeaveAndAbsences_Upgrader_Step_1020; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1021; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1022; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1023; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1024; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1025; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1026; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1027; + use CRM_HRLeaveAndAbsences_Upgrader_Step_1028; /** * A list of directories to be scanned for XML installation files diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1019.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1019.php index 0df83381d9b..9d5292b2e46 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1019.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1019.php @@ -9,13 +9,21 @@ trait CRM_HRLeaveAndAbsences_Upgrader_Step_1019 { * @return bool */ public function upgrade_1019() { - civicrm_api3('RelationshipType', 'get', [ + $type = civicrm_api3('RelationshipType', 'get', [ 'sequential' => 1, 'name_a_b' => 'has Leave Approved by', 'name_b_a' => 'is Leave Approver of', - 'api.RelationshipType.create' => ['id' => '$value.id', 'is_reserved' => 1], ]); + if ($type['count'] != 1) { + return TRUE; + } + + $type = array_shift($type['values']); + $type['is_reserved'] = 1; + + civicrm_api3('RelationshipType', 'create', $type); + return TRUE; } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1021.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1021.php new file mode 100644 index 00000000000..e0e07b3cd49 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1021.php @@ -0,0 +1,41 @@ +whereAdd('request_type = "' . LeaveRequest::REQUEST_TYPE_TOIL . '"'); + $leaveRequest->whereAdd('is_deleted = 0'); + $leaveRequest->find(); + + while ($leaveRequest->fetch()) { + $leaveRequest->to_date = substr($leaveRequest->to_date, 0, 11) . '23:45:00'; + + $leaveRequest->update(); + } + + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1022.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1022.php new file mode 100644 index 00000000000..b71850c1a3f --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1022.php @@ -0,0 +1,20 @@ +run(CRM_Core_Resources::singleton()->getPath($extension, $file)); + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1023.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1023.php new file mode 100644 index 00000000000..3ed180d83b4 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1023.php @@ -0,0 +1,24 @@ + 'hrleaveandabsences_toil_amounts', + 'name' => 'zero_days', + ]); + + if (empty($result['id'])) { + return TRUE; + } + + civicrm_api3('OptionValue', 'delete', [ + 'id' => $result['id'] + ]); + + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1025.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1025.php new file mode 100644 index 00000000000..97d1dc0a70a --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1025.php @@ -0,0 +1,132 @@ +up1025_createLeaveWorkflowOptionGroup($templateName); + + if ($result['count'] > 0) { + $this->up1025_createLeaveWorkflowOptionValue($templateName); + } + + return TRUE; + } + + /** + * Create Leave Message Template Workflow Option Group. + * + * @param string $templateName + * + * @return array + */ + public function up1025_createLeaveWorkflowOptionGroup($templateName) { + $workflow = 'Message Template Workflow for Leave'; + + $result = civicrm_api3('OptionGroup', 'create', [ + 'name' => $templateName, + 'title' => $workflow, + 'description' => $workflow, + 'is_locked' => 1, + 'is_reserved' => 1 + ]); + + // Flush constant because the option group id is cached and will not be + // available for linking newly created option group value + CRM_Core_PseudoConstant::flush(); + + return $result; + } + + /** + * Create Leave Message Template Workflow Option Values. + * + * @param string $templateName + */ + public function up1025_createLeaveWorkflowOptionValue($templateName) { + $optionValues = [ + [ + 'option_group_id' => $templateName, + 'label' => 'CiviHR Leave Request Notification', + 'name' => 'civihr_leave_request_notification', + ], + [ + 'option_group_id' => $templateName, + 'label' => 'CiviHR TOIL Request Notification', + 'name' => 'civihr_toil_request_notification', + ], + [ + 'option_group_id' => $templateName, + 'label' => 'CiviHR Sickness Record Notification', + 'name' => 'civihr_sickness_record_notification', + ] + ]; + + foreach ($optionValues as $optionValue) { + $result = civicrm_api3('OptionValue', 'create', $optionValue); + if ($result['count'] > 0) { + $this->up1025_updateLeaveMsgTemplate( + $result['id'], + $optionValue['label'] + ); + } + } + } + + /** + * Update message template workflow id for option group msg_tpl_workflow_leave + * + * @param int $workflowId + * @param string $msgLabel + */ + public function up1025_updateLeaveMsgTemplate($workflowId, $msgLabel) { + $result = civicrm_api3('MessageTemplate', 'get', [ + 'sequential' => 1, + 'return' => ['id', 'msg_title', 'msg_subject', 'msg_text', 'msg_html'], + 'msg_title' => $msgLabel, + ]); + if ($result['count'] == 1) { + // update existing record as default with new workflow id + civicrm_api3('MessageTemplate', 'create', [ + 'workflow_id' => $workflowId, + 'is_default' => 1, + 'is_reserved' => 0, + 'id' => $result['id'], + ]); + + // create the reserved version of template + $this->duplicateTemplateAsReserved($result['values'][0], $workflowId); + } else { + foreach ($result['values'] as $value) { + civicrm_api3('MessageTemplate', 'create', [ + 'workflow_id' => $workflowId, + 'id' => $value['id'], + ]); + } + } + } + + /** + * Duplicate an existing template and set is_reserved true + * + * @param array $template + * @param int $workflowId + */ + public function duplicateTemplateAsReserved($template, $workflowId) { + $newTemplate = [ + 'msg_title' => $template['msg_title'], + 'msg_subject' => $template['msg_subject'], + 'msg_text' => $template['msg_text'], + 'msg_html' => $template['msg_html'], + 'workflow_id' => $workflowId, + 'is_default' => 0, + 'is_reserved' => 1 + ]; + + civicrm_api3('MessageTemplate', 'create', $newTemplate); + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1026.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1026.php new file mode 100644 index 00000000000..b0db80a3314 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1026.php @@ -0,0 +1,130 @@ + 'id', 'name' => 'leave_and_absences']; + $parentId = (int) civicrm_api3('Navigation', 'getvalue', $params); + civicrm_api3('Navigation', 'create', ['id' => $parentId, 'weight' => -96]); + + $this->up1026_createNewLinks($parentId); + // we need to flush for new items to be recognized + CRM_Core_PseudoConstant::flush(); + $this->up1026_relabelExistingLinks($parentId); + $this->up1026_addSeparators($parentId); + $this->up1026_updateWeight($parentId); + + return TRUE; + } + + /** + * Creates new entries in the leave submenu + * + * @param int $parentId + */ + private function up1026_createNewLinks($parentId) { + $permission = 'administer leave and absences'; + $optionGroupLinks = [ + 'Sickness Reasons' => 'hrleaveandabsences_sickness_reason', + 'TOIL to be Accrued' => 'hrleaveandabsences_toil_amounts', + 'Work Pattern Change Reasons' => 'hrleaveandabsences_work_pattern_change_reason', + 'Work Pattern Day Equivalents' => 'hrleaveandabsences_leave_days_amounts' + ]; + + foreach ($optionGroupLinks as $itemName => $optionGroup) { + $link = 'civicrm/admin/options/' . $optionGroup . '?reset=1'; + $params = ['url' => $link]; + $this->up1026_createNavItem($itemName, $permission, $parentId, $params); + } + } + + /** + * Relabels some of the existing leave items + * + * @param int $parentId + */ + private function up1026_relabelExistingLinks($parentId) { + $nameToLabelMapping = [ + 'leave_and_absence_types' => ts('Leave Types'), + 'leave_and_absence_periods' => ts('Leave Periods'), + 'leave_and_absence_manage_work_patterns' => ts('Work Patterns'), + 'leave_and_absence_general_settings' => ts('Leave Settings'), + 'leave_and_absences_import' => ts('Import Leave Requests'), + ]; + + foreach ($nameToLabelMapping as $name => $label) { + $params = ['parent_id' => $parentId, 'name' => $name, 'return' => 'id']; + $id = (int) civicrm_api3('Navigation', 'getvalue', $params); + civicrm_api3('Navigation', 'create', ['id' => $id, 'label' => $label]); + } + } + + /** + * Adds separators after certain items in the leave submenu + * + * @param int $parentId + */ + private function up1026_addSeparators($parentId) { + $itemsWithSeparators = [ + 'leave_and_absence_general_settings', + 'Work Pattern Day Equivalents', + ]; + + foreach ($itemsWithSeparators as $name) { + $params = ['parent_id' => $parentId, 'name' => $name, 'return' => 'id']; + $id = (int) civicrm_api3('Navigation', 'getvalue', $params); + civicrm_api3('Navigation', 'create', ['id' => $id, 'has_separator' => 1]); + } + } + + /** + * Sets the weight for the "Import" item so it will appear last + * + * @param int $parentId + */ + private function up1026_updateWeight($parentId) { + $name = 'leave_and_absences_import'; + $params = ['parent_id' => $parentId, 'name' => $name, 'return' => 'id']; + $id = (int) civicrm_api3('Navigation', 'getvalue', $params); + $maxWeight = CRM_Core_BAO_Navigation::calculateWeight($parentId); + civicrm_api3('Navigation', 'create', ['id' => $id, 'weight' => $maxWeight]); + } + + /** + * Creates a navigation menu item using the API + * + * @param string $name + * @param string $permission + * @param int $parentID + * @param array $params + * + * @return array + */ + private function up1026_createNavItem( + $name, + $permission, + $parentID, + $params = [] + ) { + $params = array_merge([ + 'name' => $name, + 'label' => ts($name), + 'permission' => $permission, + 'parent_id' => $parentID, + 'is_active' => 1, + ], $params); + + $existing = civicrm_api3('Navigation', 'get', $params); + + if ($existing['count'] > 0) { + return array_shift($existing['values']); + } + + return civicrm_api3('Navigation', 'create', $params); + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1027.php b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1027.php new file mode 100644 index 00000000000..93b94229c63 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/CRM/HRLeaveAndAbsences/Upgrader/Step/1027.php @@ -0,0 +1,30 @@ + '$today'"); + + return TRUE; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/api/v3/LeaveBalanceChangeExpiryLog.php b/uk.co.compucorp.civicrm.hrleaveandabsences/api/v3/LeaveBalanceChangeExpiryLog.php new file mode 100644 index 00000000000..47d53a00a7a --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/api/v3/LeaveBalanceChangeExpiryLog.php @@ -0,0 +1,14 @@ +isCalculationUnitInHours()) { + if($absenceType->isCalculationUnitInHours() || + $params['request_type'] === CRM_HRLeaveAndAbsences_BAO_LeaveRequest::REQUEST_TYPE_TOIL) { return; } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/css/leaveandabsence.css b/uk.co.compucorp.civicrm.hrleaveandabsences/css/leaveandabsence.css index 09e1ca024da..8fbc3f4b460 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/css/leaveandabsence.css +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/css/leaveandabsence.css @@ -1 +1 @@ -#bootstrap-theme .chr_disabled{opacity:0.5;pointer-events:none}#bootstrap-theme .table-condensed>thead>tr>th{background:#fff !important;padding:8px 5px}#bootstrap-theme .table-condensed-mixed>thead>tr>th,#bootstrap-theme .table-condensed-mixed>thead>tr>td,#bootstrap-theme .table-condensed-mixed>tbody>tr>th,#bootstrap-theme .table-condensed-mixed>tbody>tr>td{padding-left:5px;padding-right:5px}#bootstrap-theme .table-condensed>tbody>tr>td:first-child,#bootstrap-theme .table-condensed>tbody>tr>th:first-child,#bootstrap-theme .table-condensed>thead>tr>td:first-child,#bootstrap-theme .table-condensed>thead>tr>th:first-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>td:first-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>th:first-child,#bootstrap-theme .table-condensed-mixed>thead>tr>td:first-child,#bootstrap-theme .table-condensed-mixed>thead>tr>th:first-child{padding-left:20px}#bootstrap-theme .table-condensed>tbody>tr>td:last-child,#bootstrap-theme .table-condensed>tbody>tr>th:last-child,#bootstrap-theme .table-condensed>thead>tr>td:last-child,#bootstrap-theme .table-condensed>thead>tr>th:last-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>td:last-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>th:last-child,#bootstrap-theme .table-condensed-mixed>thead>tr>td:last-child,#bootstrap-theme .table-condensed-mixed>thead>tr>th:last-child{padding-right:20px}#bootstrap-theme .table-nested{overflow-y:hidden;position:relative}#bootstrap-theme .table-nested:before{box-shadow:inset 0px 6px 9px -6px rgba(0,0,0,0.2);content:'';display:block;height:10px;left:0;position:absolute;top:0;width:100%;z-index:10}#bootstrap-theme .table-nested:after{box-shadow:inset 0px -4px 9px -6px rgba(0,0,0,0.2);content:'';display:block;height:10px;left:0;position:absolute;bottom:0;width:100%;z-index:10}#bootstrap-theme .table-nested>table,#bootstrap-theme .table-nested>.table{background-color:#fff}#bootstrap-theme .table-nested>table>tbody>tr>td:first-child,#bootstrap-theme .table-nested>table>tbody>tr>th:first-child,#bootstrap-theme .table-nested>table>thead>tr>td:first-child,#bootstrap-theme .table-nested>table>thead>tr>th:first-child,#bootstrap-theme .table-nested>.table>tbody>tr>td:first-child,#bootstrap-theme .table-nested>.table>tbody>tr>th:first-child,#bootstrap-theme .table-nested>.table>thead>tr>td:first-child,#bootstrap-theme .table-nested>.table>thead>tr>th:first-child{padding-left:30px;position:relative}#bootstrap-theme .table-nested>table>tbody>tr>td:first-child:before,#bootstrap-theme .table-nested>table>tbody>tr>th:first-child:before,#bootstrap-theme .table-nested>table>thead>tr>td:first-child:before,#bootstrap-theme .table-nested>table>thead>tr>th:first-child:before,#bootstrap-theme .table-nested>.table>tbody>tr>td:first-child:before,#bootstrap-theme .table-nested>.table>tbody>tr>th:first-child:before,#bootstrap-theme .table-nested>.table>thead>tr>td:first-child:before,#bootstrap-theme .table-nested>.table>thead>tr>th:first-child:before{background:#C2CFD8;content:'';display:block;height:110%;left:0;position:absolute;top:0;width:10px;z-index:2}#bootstrap-theme .table-nested>table>tbody>tr>td:last-child,#bootstrap-theme .table-nested>table>tbody>tr>th:last-child,#bootstrap-theme .table-nested>table>thead>tr>td:last-child,#bootstrap-theme .table-nested>table>thead>tr>th:last-child,#bootstrap-theme .table-nested>.table>tbody>tr>td:last-child,#bootstrap-theme .table-nested>.table>tbody>tr>th:last-child,#bootstrap-theme .table-nested>.table>thead>tr>td:last-child,#bootstrap-theme .table-nested>.table>thead>tr>th:last-child{padding-right:30px;position:relative}#bootstrap-theme .table-nested>table>tbody>tr>td:last-child:after,#bootstrap-theme .table-nested>table>tbody>tr>th:last-child:after,#bootstrap-theme .table-nested>table>thead>tr>td:last-child:after,#bootstrap-theme .table-nested>table>thead>tr>th:last-child:after,#bootstrap-theme .table-nested>.table>tbody>tr>td:last-child:after,#bootstrap-theme .table-nested>.table>tbody>tr>th:last-child:after,#bootstrap-theme .table-nested>.table>thead>tr>td:last-child:after,#bootstrap-theme .table-nested>.table>thead>tr>th:last-child:after{background:#C2CFD8;content:'';display:block;height:110%;right:0;position:absolute;top:0;width:10px;z-index:2}@media screen and (max-width: 767px){#bootstrap-theme .table-nested.table-responsive{border:0;margin-bottom:0}}#bootstrap-theme .table-nested-cell{padding:0 !important}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(1){width:40%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(2){width:15%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(3){width:35%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(4){width:10%}#bootstrap-theme .chr_absence-work-pattern__work-pattern-listing{display:inline-block}#bootstrap-theme .chr_absence-work-pattern__alert{margin-bottom:0 !important}#bootstrap-theme .chr_annual-entitlements__period{width:130px}#bootstrap-theme .chr_annual-entitlements__edit-entitlements{width:150px}#bootstrap-theme .chr_contract-entitlements__position{width:140px}@media (max-width: 992px){#bootstrap-theme .chr_leave-balance-tab .chr_leave-balance-tab__filter:not(:last-child){padding-bottom:15px}}#bootstrap-theme .chr_leave-balance-tab__body{padding:0}@media (min-width: 1200px){#bootstrap-theme .chr_leave-calendar__dates-container .chr_leave-calendar{table-layout:fixed}}#bootstrap-theme .chr_leave-calendar__names-container .chr_leave-calendar{table-layout:fixed}#bootstrap-theme .chr_leave-calendar__day{font-size:10px !important;line-height:1.4em !important;padding:10px !important;text-align:center !important}@media (min-width: 1200px){#bootstrap-theme .chr_leave-calendar__day{padding:10px 0 !important}}#bootstrap-theme .chr_leave-calendar__day--disabled{opacity:0.5}#bootstrap-theme .chr_leave-calendar__day--current{color:#0071BD !important}#bootstrap-theme .chr_leave-calendar__item{color:#FFF;display:block;font-size:10px;height:100%;position:relative;text-align:center;text-transform:uppercase;width:100%}#bootstrap-theme .chr_leave-calendar__item>span{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;height:1.2em}#bootstrap-theme .chr_leave-calendar__item>.chr_leave-calendar__time-unit{font-size:7px;height:1em;margin-left:-1px}#bootstrap-theme .chr_leave-calendar__item>a{cursor:pointer;bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}#bootstrap-theme .chr_leave-calendar__item--disabled{cursor:not-allowed;opacity:0.5}#bootstrap-theme .chr_leave-calendar__item--type--late{background-color:#eca67e;border-color:#eca67e}#bootstrap-theme .chr_leave-calendar__item--type--non-working{background-color:#41afcb !important;border-color:#41afcb}#bootstrap-theme .chr_leave-calendar__item--type--public-holiday{background-color:#8ec68a !important;border-color:#8ec68a}#bootstrap-theme .chr_leave-calendar__item--type--weekend{background-color:#c7cbd0 !important;border-color:#c7cbd0}#bootstrap-theme .chr_leave-calendar__item--alt{background:#FFF !important;border:1px solid transparent;color:#464354}#bootstrap-theme .chr_leave-calendar__item--requested:before{background:#c7cbd0;content:'';display:block;height:.5em;position:absolute;width:100%;top:0}#bootstrap-theme .chr_leave-calendar__item--toil-requested:before{background:red;content:'';display:block;height:.5em;left:-1px;position:absolute;width:calc(100% + 2px);top:-1px}#bootstrap-theme .chr_leave-calendar__items>td{overflow:hidden;height:35px;padding:0 !important}#bootstrap-theme .chr_leave-calendar__items leave-calendar-day{display:block;height:100%}#bootstrap-theme .chr_leave-calendar__legend__title{font-size:12px}#bootstrap-theme .chr_leave-calendar__legend>.row:not(:first-child){margin-top:20px}#bootstrap-theme .chr_leave-calendar__legend .chr_leave-calendar__legend__entry{margin-top:10px}@media (min-width: 768px){#bootstrap-theme .chr_leave-calendar__legend .chr_leave-calendar__legend__entry{margin-top:0}}#bootstrap-theme .chr_leave-calendar__legend__entry{overflow:auto}#bootstrap-theme .chr_leave-calendar__legend__entry+#bootstrap-theme .chr_leave-calendar__legend__entry{margin-top:10px}#bootstrap-theme .chr_leave-calendar__legend__entry>.chr_leave-calendar__item{font-size:8px;height:20px;margin-right:10px;position:absolute;width:20px}#bootstrap-theme .chr_leave-calendar__legend__label{display:inline-block;font-size:12px;margin-left:26px}#bootstrap-theme .chr_leave-calendar__month-header{background:#F3F6F7}#bootstrap-theme .chr_leave-calendar__month-header .panel-title{font-size:16px}#bootstrap-theme td.chr_leave-calendar__name,#bootstrap-theme th.chr_leave-calendar__name{font-size:12px !important;line-height:100%;padding:0 20px !important;text-align:left;text-overflow:ellipsis;width:100%}#bootstrap-theme th.chr_leave-calendar__name,#bootstrap-theme th.chr_leave-calendar__day{height:49px}#bootstrap-theme th.chr_leave-calendar__name{padding-bottom:10px !important}#bootstrap-theme td.chr_leave-calendar__name{vertical-align:middle !important}#bootstrap-theme .chr_leave-calendar__pagination{font-size:10px;text-align:center}#bootstrap-theme .chr_leave-calendar__pagination [class*="btn"]{outline:none;padding:0;line-height:1em}#bootstrap-theme .chr_leave-calendar__pagination [class*="btn"] .fa{color:#555}#bootstrap-theme .chr_leave-calendar__pagination [class*="btn"][disabled] .fa{opacity:0.5}#bootstrap-theme .chr_leave-calendar__pagination [class*="btn"]:hover:not([disabled]) .fa{color:#464354}#bootstrap-theme .chr_leave-calendar__pagination-next{border-top:none}#bootstrap-theme .chr_leave-calendar__pagination-next th{height:24px;padding:4px 0 6px !important}#bootstrap-theme .chr_leave-calendar__pagination-next .chr_leave-calendar__pagination{padding-right:3px !important}#bootstrap-theme .chr_leave-calendar__month-container{margin:0}#bootstrap-theme .chr_leave-calendar__month-container>div{padding:0}#bootstrap-theme .chr_leave-calendar__dates-container{overflow-x:auto}#bootstrap-theme .chr_leave-calendar__admin-filters-hint{display:inline-block;font-size:20px;vertical-align:middle}#bootstrap-theme .chr_leave-calendar__admin-filters-select{width:calc(100% - 50px);display:inline-block;margin-right:20px}#bootstrap-theme .chr_leave-report .dropdown-toggle{color:#464354;padding:0 10px}#bootstrap-theme .chr_leave-report .dropdown-toggle:hover{background:#e6e6e6}#bootstrap-theme .chr_leave-report table{table-layout:fixed}#bootstrap-theme .chr_leave-report table thead th,#bootstrap-theme .chr_leave-report table tbody td{padding:8px 5px}#bootstrap-theme .chr_leave-report__label{color:#464354;font-weight:700}#bootstrap-theme .chr_leave-report__label>.fa{margin-right:5px}#bootstrap-theme .chr_leave-report__label--toggle{cursor:pointer;user-select:none}#bootstrap-theme .chr_leave-report__heading{background-color:#F3F6F7;border-bottom:1px solid #dadcde}#bootstrap-theme .chr_leave-report__heading .chr_leave-report__export-button{line-height:2.4}#bootstrap-theme .chr_leave-report__table table,#bootstrap-theme .chr_leave-report__table .table{border-collapse:separate}#bootstrap-theme .chr_leave-report__table table>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>tbody>tr:first-child>td{border-top-width:0}#bootstrap-theme .chr_leave-report__table table>thead+tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>thead+tbody>tr:first-child>td{border-top-width:1px}#bootstrap-theme .chr_leave-report__table table:not(.table-bordered):not(.table-condensed)>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table:not(.table-bordered):not(.table-condensed)>tbody>tr:first-child>td{border-color:#F3F6F7}#bootstrap-theme .chr_leave-report__table table>thead>tr>th,#bootstrap-theme .chr_leave-report__table .table>thead>tr>th{background:#F3F6F7;border-bottom:0;color:#464354;text-transform:capitalize}#bootstrap-theme .chr_leave-report__table table>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>tbody>tr:first-child>td{border-color:#E8EEF0 !important}#bootstrap-theme .chr_leave-report__table table>tfoot>tr,#bootstrap-theme .chr_leave-report__table .table>tfoot>tr{background:#F3F6F7}#bootstrap-theme .chr_leave-report__table>table>thead>tr>th,#bootstrap-theme .chr_leave-report__table>.table>thead>tr>th{padding-bottom:13px;padding-top:13px}#bootstrap-theme .chr_leave-report__table-container{overflow:auto}#bootstrap-theme .chr_leave-report__table-container .panel{display:inline-block;min-width:100%}#bootstrap-theme .chr_leave-report__table__heading--action{width:45px}#bootstrap-theme .chr_leave-report__table__heading--label{width:280px}#bootstrap-theme .chr_leave-report__table__heading--dates{width:170px}#bootstrap-theme .chr_leave-report__table__heading--status{width:180px}#bootstrap-theme .chr_leave-report__table__heading--type{width:65px;word-break:break-word}#bootstrap-theme .chr_leave-request-comment{margin-top:10px}#bootstrap-theme .chr_leave-request-comment__text{border-bottom:1px solid #E8EEF0;color:#C2CFD8;margin-right:10px;padding-bottom:20px}#bootstrap-theme .chr_leave-request-files_list{height:150px;overflow-y:auto;margin-top:20px;margin-bottom:20px}#bootstrap-theme .chr_leave-request-files_meta{margin-bottom:10px}#bootstrap-theme .chr_leave-request-files_upload{border:dashed 1px #464354;padding:20px}#bootstrap-theme .chr_leave-request-files_upload_action{padding:5px}#bootstrap-theme .chr_leave-request-files_file-name{display:inline-block;max-width:240px;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom}#bootstrap-theme .chr_leave-request-files_delete{margin-top:-7px}#bootstrap-theme .chr_leave-request-modal .modal-title{font-size:18px !important}#bootstrap-theme .chr_leave-request-modal .table-responsive{border:0}#bootstrap-theme .chr_leave-request-modal .chr_leave-request-date-picker-container .input-group{width:100%}@media screen and (max-width: 767px){#bootstrap-theme .chr_leave-request-modal .chr_leave-request-date-picker-container{margin-bottom:10px}}#bootstrap-theme .chr_leave-request-modal__chevron{font-size:0.6em;margin-right:5px;vertical-align:middle}#bootstrap-theme .chr_leave-request-modal__comments{height:230px;margin-bottom:20px;overflow:auto}#bootstrap-theme .chr_leave-request-modal__comments_empty{margin-bottom:20px}#bootstrap-theme .chr_leave-request-modal__footer{margin:0}#bootstrap-theme .chr_leave-request-modal__delete{margin-left:15px;margin-top:8px}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container{margin-bottom:20px}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container ul{opacity:1 !important}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container:not(.ui-select-multiple) input{width:100% !important}#bootstrap-theme .chr_leave-request-modal__form-group,#bootstrap-theme .chr_leave-request-modal__required-documents>div{margin-bottom:15px}#bootstrap-theme .chr_leave-request-modal__response{padding:20px 20px 0}#bootstrap-theme .chr_leave-request-modal__response label{font-size:17px;margin-top:-3px}#bootstrap-theme .chr_leave-request-modal__response .chr_wysiwyg{margin-top:15px}#bootstrap-theme .chr_leave-request-modal__required-documents input{margin-right:5px}#bootstrap-theme .chr_leave-request-modal__small_spinner>div.chr_spinner{margin-top:18px;min-height:initial}#bootstrap-theme .chr_leave-request-modal__tab input[uib-datepicker-popup]{font-size:13px}#bootstrap-theme .chr_leave-request-modal__table{border:1px solid #F3F6F7;margin-bottom:15px !important}#bootstrap-theme .chr_leave-request-modal__user-info{font-size:17px;padding:20px}#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(1){color:#464354}#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(2){color:#555}@media screen and (min-width: 480px){#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(2){border-left:1px solid #E8EEF0}}#bootstrap-theme .chr_leave-request-modal__span-expiry{display:inline-block;margin-top:7px}#bootstrap-theme .chr_leave-request-modal__expiry-clear{position:absolute;right:3.5em;top:0.6em;z-index:2}#bootstrap-theme .chr_leave-request-modal__small-text{font-size:80%}#bootstrap-theme .chr_leave-request-modal__custom-deduction-toggling-row{margin-top:-5px}@media screen and (min-width: 768px){#bootstrap-theme .chr_leave-request-modal__custom-deduction-label{text-align:right}}@media screen and (max-width: 767px){#bootstrap-theme .chr_leave-request-modal__custom-deduction-label{margin-bottom:10px}}#bootstrap-theme .chr_leave-request-modal .form-group{overflow:inherit !important}#bootstrap-theme .chr_leave-request-modal .alert{margin-bottom:0 !important}#bootstrap-theme .chr_leave-request-modal input[uib-datepicker-popup]{box-shadow:none !important;background-color:inherit !important;color:inherit !important;cursor:pointer !important;border-right:none}#bootstrap-theme .leave-widget h4{color:#4D4D69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px}#bootstrap-theme .leave-widget__types>table,#bootstrap-theme .leave-widget__sickness>table,#bootstrap-theme .leave-widget__next-leave>table{border:none}#bootstrap-theme .leave-widget__types>table thead tr th,#bootstrap-theme .leave-widget__sickness>table thead tr th,#bootstrap-theme .leave-widget__next-leave>table thead tr th{color:#4D4D69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px;background:none;width:35%}#bootstrap-theme .leave-widget__types>table thead tr th:first-child,#bootstrap-theme .leave-widget__sickness>table thead tr th:first-child,#bootstrap-theme .leave-widget__next-leave>table thead tr th:first-child{width:65%}#bootstrap-theme .leave-widget__types>table tbody tr td,#bootstrap-theme .leave-widget__sickness>table tbody tr td,#bootstrap-theme .leave-widget__next-leave>table tbody tr td{color:#0071BD;font-size:16px;font-weight:600;padding-bottom:9px}#bootstrap-theme .leave-widget__types>table tbody tr td:first-child,#bootstrap-theme .leave-widget__sickness>table tbody tr td:first-child,#bootstrap-theme .leave-widget__next-leave>table tbody tr td:first-child{color:#464354}#bootstrap-theme .leave-widget hr{border-color:#DEE4ED;margin-bottom:25px;margin-top:25px}#bootstrap-theme .leave-widget__sickness h4{margin-top:18px}#bootstrap-theme .leave-widget__next-leave h3{font-size:16px;margin-bottom:16px;margin-top:0}#bootstrap-theme .leave-widget__next-leave__deduction{font-size:16px;font-weight:600;color:#464354}#bootstrap-theme .chr_leave__page-selector-dropdown{margin-right:5px;position:relative;top:1px;width:calc(100% - 80px)}#bootstrap-theme .chr_leave__page-selector-dropdown select{height:40px}#bootstrap-theme .chr_leave__page-selector-dropdown .crm_custom-select__arrow{line-height:40px;width:40px}#bootstrap-theme leave-request-record-actions .dropdown-menu{left:auto;right:0}#bootstrap-theme leave-request-record-actions .dropdown-toggle{height:40px}#bootstrap-theme leave-request-record-actions i.fa{margin-right:8px}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;border-bottom:1px solid #dadcde;margin:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header .panel-title{margin-top:7px;display:inline-block}@media screen and (max-width: 992px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header>div:not(:last-child),#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header .panel-title{padding-bottom:20px}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter{display:inline-block;margin-top:7px;white-space:nowrap}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter .fa{font-size:0.6em;margin-right:5px;margin-top:-2px;vertical-align:middle}@media screen and (max-width: 991px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter{margin-top:15px}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;border-bottom:1px solid #dadcde;margin:0;padding-top:15px}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>*{padding-left:10px !important;padding-right:10px !important}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>div:not(:last-child){padding-bottom:20px}}@media screen and (min-width: 992px) and (max-width: 1199px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>.no_gutter{padding-bottom:0 !important}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body{margin:0;padding:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body [class^="col-"],#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body [class*=" col-"]{padding:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body a{cursor:pointer}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container{padding-left:10px;padding-right:10px;background-color:#f7f7f9}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container>div{padding-left:15px;padding-right:15px}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .form-group{overflow:inherit !important}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .panel{background-image:none !important}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .panel-body,#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .chr_vertical_tabs{background-color:#f7f7f9}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] input[type="search"]{width:100% !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header .checkbox{margin-top:5px}#bootstrap-theme .page-manager-leave .chr_manage_leave_requests .btn-sm{font-size:100% !important}#bootstrap-theme .chr_manager_calendar__header{padding-left:10px;padding-right:10px;padding-top:15px;margin:0;background-color:#f7f7f9;border-bottom:1px solid #dadcde}#bootstrap-theme .chr_manager_calendar__header>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manager_calendar__header .checkbox{margin:0}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manager_calendar__header>div:not(:last-child){padding-bottom:20px}}#bootstrap-theme .chr_manager_calendar__sub-header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;margin:0}#bootstrap-theme .chr_manager_calendar__sub-header>*{padding-left:10px !important;padding-right:10px !important}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manager_calendar__sub-header>div:not(:last-child){padding-bottom:20px}#bootstrap-theme .chr_manager_calendar__sub-header .ui-select-container{height:auto}}#bootstrap-theme .annual-entitlement-change-log-component table thead td{min-width:100px}#bootstrap-theme .annual-entitlement-change-log-component table thead td.annual-entitlement-change-log-component__comments{min-width:300px}#bootstrap-theme .time-amount-picker .crm_custom-select{display:inline-block;margin-right:2px}#bootstrap-theme .time-amount-picker .crm_custom-select:nth-child(2){margin-left:10px}#bootstrap-theme .absence-tab-page .btn-group{margin-bottom:20px}#bootstrap-theme .absence-tab-page .btn-group>.btn{border-color:transparent !important}#bootstrap-theme .absence-tab-page .tab-pane{padding:0 !important}#bootstrap-theme .absence-tab-page .tab-content{background-color:transparent !important}#bootstrap-theme .crm-absence_type-form-block .crm-section .label{width:35%}#bootstrap-theme .crm-absence_type-form-block .crm-section .content{margin-left:40%}#bootstrap-theme .crm-absence_type-form-block .toil-option,#bootstrap-theme .crm-absence_type-form-block .carry-forward-option,#bootstrap-theme .crm-absence_type-form-block .toil-expiration,#bootstrap-theme .crm-absence_type-form-block .carry-forward-expiration-duration,#bootstrap-theme .crm-absence_type-form-block .carry-forward-expiration-date{display:none}#bootstrap-theme .crm-absence_type-form-block .sp-replacer{padding:2px}#bootstrap-theme .crm-absence_type-form-block .sp-preview{height:15px;width:15px}#bootstrap-theme .crm-absence_type-form-block .sp-dd{height:0;line-height:15px;font-size:9px}.page-civicrm-leaveandabsences-dashboard h1.page-title,.page-civicrm-leaveandabsences-dashboard #branding{display:none !important}.page-civicrm-leaveandabsences-dashboard #page{margin:0;padding:0}.admin-dashboard-page{position:relative}.admin-dashboard-page .crm_page__topbar{height:65px}.admin-dashboard-page .crm_page__topbar .dropdown-toggle{margin:15px 30px 0 0 !important}.admin-dashboard-page .crm_page__topbar .dropdown-toggle+ul{margin-right:30px !important}.admin-dashboard-page .chr_admin-dashboard_side-nav{overflow:hidden;width:170px;position:absolute;height:calc(100% - 12px);background-color:#fff}.admin-dashboard-page .chr_admin-dashboard_side-nav li.active{background:#E8EEF0}.admin-dashboard-page .chr_admin-dashboard_content{float:right;width:calc(100% - 170px - 16px * 2);margin:16px;margin-bottom:0}#bootstrap-theme #calculation-details{background:#fff}#bootstrap-theme #calculation-details .base-contractual-entitlement{color:#0071BD}#bootstrap-theme #calculation-details .working-days-to-work{color:#44CB7E}#bootstrap-theme #calculation-details .working-days-in-period{color:#E6AB5E}#bootstrap-theme #calculation-details .contract-1-pro-rata{color:#E6807F}#bootstrap-theme #calculation-details .contract-2-pro-rata{color:#797300}#bootstrap-theme #calculation-details .contract-3-pro-rata{color:#904E1E}#bootstrap-theme #calculation-details .contract-4-pro-rata{color:#0511B1}#bootstrap-theme #calculation-details .contract-5-pro-rata{color:#4B9609}#bootstrap-theme #calculation-details .calculation-pro-rata{color:#95c0ff}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body{padding-top:20px;padding-bottom:20px}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body .row:first-child h3{margin-top:0}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body h3{margin-bottom:20px}#bootstrap-theme .crm-leave-and-absences-form-block .panel-footer .crm-button:last-child{margin-right:0}#bootstrap-theme.crm-leave-and-balance-import .panel{background-color:#fff}#bootstrap-theme.crm-leave-and-balance-import .panel-header{position:relative}#bootstrap-theme.crm-leave-and-balance-import .panel-header h2{padding:10px 20px}#bootstrap-theme.crm-leave-and-balance-import .panel-body .row:not(:last-child){padding-bottom:2em}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats .label{display:none}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats label{font-weight:normal !important}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats td{border:0;padding:0}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block{box-shadow:none;padding:0}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table{margin-bottom:2em;width:100%}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table th{padding:10px 20px;border-right:none}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table th,#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table td{padding:5px}#bootstrap-theme.crm-leave-and-balance-import #preview-counts,#bootstrap-theme.crm-leave-and-balance-import #summary-counts{box-shadow:none;margin-bottom:2em;width:100%}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td{background-color:#f2dede !important;color:#CF3458}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td a,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td a{color:#bd2d4e;font-weight:bold}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td a:hover,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td a:hover{color:#0062a4}#bootstrap-theme.manage-entitlements-form .wider-hr{margin-left:-20px;margin-right:-20px;border-width:2px}#bootstrap-theme.manage-entitlements-form .wider-row{margin-left:-20px;margin-right:-20px}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters{padding:15px 0;text-align:center}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .override-filters label{display:inline-block}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .override-filters label:before{display:none}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .absence-type-filter{margin-right:10px}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .col-sm-4:last-child{text-align:right}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list{margin-bottom:0}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement-header .title{float:left;width:65%}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement-header .actions{float:right}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list tr.hidden{display:none}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .absence-type{color:#fff;display:inline-block;padding:5px}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement .overridden-proposed-entitlement,#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement .calculation-unit{display:none}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .borderless-button{background-color:transparent;border:0;cursor:pointer}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .add-comment{font-size:1.1em}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .comment-text{display:none}#bootstrap-theme.manage-entitlements-form .manage-entitlements-form__filters{padding-bottom:1em}#bootstrap-theme.manage-entitlements-form .table{background:#f9f9f9;border-top:1px solid #E8EEF0;border-bottom:1px solid #E8EEF0;margin-bottom:2em}#bootstrap-theme.manage-entitlements-form .table th{background:#F3F6F7 !important}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header{border-left:1px solid #E8EEF0;border-right:1px solid #E8EEF0;background:#e4ebed !important;min-width:200px}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .row>div{display:table-cell;float:none;vertical-align:bottom}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .fa{color:#4D4D69}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .action-button-container{padding:0}#bootstrap-theme.manage-entitlements-form .table td.proposed-entitlement{border-left:1px solid #E8EEF0;border-right:1px solid #E8EEF0;background:white}#bootstrap-theme.manage-entitlements-form .table span.absence-type{border-radius:3px;padding:0 5px}#bootstrap-theme.manage-entitlements-form .table tbody .fa{color:#0071BD}#bootstrap-theme.manage-entitlements-form .crm-container .CRM_HRLeaveAndAbsences_Form_ManageEntitlements .crm-button-type-next{float:right !important}#bootstrap-theme.manage-entitlements-form .panel-footer{border-top:none}#add-comment-dialog{display:none}#add-comment-dialog .calculation_comment{box-sizing:border-box;padding:10px;width:100%}#bootstrap-theme .crm-work-pattern-form-block .ui-tabs.ui-widget-content{background:none}#bootstrap-theme .work-pattern-calendar .number-of-weeks{padding:15px 0 15px 0}#bootstrap-theme .work-pattern-calendar .work-pattern-week{border-top:1px solid rgba(0,0,0,0.2);padding:15px 0 15px 0;margin-bottom:15px}#bootstrap-theme .work-pattern-calendar .work-pattern-week.hidden-week{display:none}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-number{float:left;font-weight:bold;padding:5px 0 15px 5px}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days{table-layout:fixed}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-hours{float:right;padding:5px 5px 15px 0}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-hours .number-of-hours{font-weight:bold}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days td{padding:5px 10px 5px 10px}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days input{min-width:0;text-align:center}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days select{min-width:0;width:100% !important}#bootstrap-theme .work-pattern-calendar .work-pattern-week .hours-row td{padding-top:15px;padding-bottom:15px;border-top:1px solid rgba(0,0,0,0.2);border-bottom:1px solid rgba(0,0,0,0.2)}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:2px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.5384615385;color:#4D4D69;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#42425a;background-color:#F3F6F7}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0071BD}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#E8EEF0}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.5384615385;color:#464354;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{left:0;right:auto}}.dropdown-header{padding:11px 20px}.dropdown-menu{-webkit-box-shadow:0 3px 18px 0 rgba(48,40,40,0.25);box-shadow:0 3px 18px 0 rgba(48,40,40,0.25);border:0;margin:0;padding:0}.dropdown-menu>li{border:0;margin:0;padding:0}.dropdown-menu>li>a{padding:11px 20px} +#bootstrap-theme .chr_disabled{opacity:0.5;pointer-events:none}#bootstrap-theme .table-condensed>thead>tr>th{background:#fff !important;padding:8px 5px}#bootstrap-theme .table-condensed-mixed>thead>tr>th,#bootstrap-theme .table-condensed-mixed>thead>tr>td,#bootstrap-theme .table-condensed-mixed>tbody>tr>th,#bootstrap-theme .table-condensed-mixed>tbody>tr>td{padding-left:5px;padding-right:5px}#bootstrap-theme .table-condensed>tbody>tr>td:first-child,#bootstrap-theme .table-condensed>tbody>tr>th:first-child,#bootstrap-theme .table-condensed>thead>tr>td:first-child,#bootstrap-theme .table-condensed>thead>tr>th:first-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>td:first-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>th:first-child,#bootstrap-theme .table-condensed-mixed>thead>tr>td:first-child,#bootstrap-theme .table-condensed-mixed>thead>tr>th:first-child{padding-left:20px}#bootstrap-theme .table-condensed>tbody>tr>td:last-child,#bootstrap-theme .table-condensed>tbody>tr>th:last-child,#bootstrap-theme .table-condensed>thead>tr>td:last-child,#bootstrap-theme .table-condensed>thead>tr>th:last-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>td:last-child,#bootstrap-theme .table-condensed-mixed>tbody>tr>th:last-child,#bootstrap-theme .table-condensed-mixed>thead>tr>td:last-child,#bootstrap-theme .table-condensed-mixed>thead>tr>th:last-child{padding-right:20px}#bootstrap-theme .table-nested{overflow-y:hidden;position:relative}#bootstrap-theme .table-nested:before{box-shadow:inset 0px 6px 9px -6px rgba(0,0,0,0.2);content:'';display:block;height:10px;left:0;position:absolute;top:0;width:100%;z-index:10}#bootstrap-theme .table-nested:after{box-shadow:inset 0px -4px 9px -6px rgba(0,0,0,0.2);content:'';display:block;height:10px;left:0;position:absolute;bottom:0;width:100%;z-index:10}#bootstrap-theme .table-nested>table,#bootstrap-theme .table-nested>.table{background-color:#fff}#bootstrap-theme .table-nested>table>tbody>tr>td:first-child,#bootstrap-theme .table-nested>table>tbody>tr>th:first-child,#bootstrap-theme .table-nested>table>thead>tr>td:first-child,#bootstrap-theme .table-nested>table>thead>tr>th:first-child,#bootstrap-theme .table-nested>.table>tbody>tr>td:first-child,#bootstrap-theme .table-nested>.table>tbody>tr>th:first-child,#bootstrap-theme .table-nested>.table>thead>tr>td:first-child,#bootstrap-theme .table-nested>.table>thead>tr>th:first-child{padding-left:30px;position:relative}#bootstrap-theme .table-nested>table>tbody>tr>td:first-child:before,#bootstrap-theme .table-nested>table>tbody>tr>th:first-child:before,#bootstrap-theme .table-nested>table>thead>tr>td:first-child:before,#bootstrap-theme .table-nested>table>thead>tr>th:first-child:before,#bootstrap-theme .table-nested>.table>tbody>tr>td:first-child:before,#bootstrap-theme .table-nested>.table>tbody>tr>th:first-child:before,#bootstrap-theme .table-nested>.table>thead>tr>td:first-child:before,#bootstrap-theme .table-nested>.table>thead>tr>th:first-child:before{background:#c2cfd8;content:'';display:block;height:110%;left:0;position:absolute;top:0;width:10px;z-index:2}#bootstrap-theme .table-nested>table>tbody>tr>td:last-child,#bootstrap-theme .table-nested>table>tbody>tr>th:last-child,#bootstrap-theme .table-nested>table>thead>tr>td:last-child,#bootstrap-theme .table-nested>table>thead>tr>th:last-child,#bootstrap-theme .table-nested>.table>tbody>tr>td:last-child,#bootstrap-theme .table-nested>.table>tbody>tr>th:last-child,#bootstrap-theme .table-nested>.table>thead>tr>td:last-child,#bootstrap-theme .table-nested>.table>thead>tr>th:last-child{padding-right:30px;position:relative}#bootstrap-theme .table-nested>table>tbody>tr>td:last-child:after,#bootstrap-theme .table-nested>table>tbody>tr>th:last-child:after,#bootstrap-theme .table-nested>table>thead>tr>td:last-child:after,#bootstrap-theme .table-nested>table>thead>tr>th:last-child:after,#bootstrap-theme .table-nested>.table>tbody>tr>td:last-child:after,#bootstrap-theme .table-nested>.table>tbody>tr>th:last-child:after,#bootstrap-theme .table-nested>.table>thead>tr>td:last-child:after,#bootstrap-theme .table-nested>.table>thead>tr>th:last-child:after{background:#c2cfd8;content:'';display:block;height:110%;right:0;position:absolute;top:0;width:10px;z-index:2}@media screen and (max-width: 767px){#bootstrap-theme .table-nested.table-responsive{border:0;margin-bottom:0}}#bootstrap-theme .table-nested-cell{padding:0 !important}#bootstrap-theme .chr_absence-work-pattern__add-custom{margin-bottom:20px}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(1){width:40%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(2){width:15%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(3){width:35%}#bootstrap-theme .chr_absence-work-pattern__custom-work-pattern td:nth-child(4){width:10%}#bootstrap-theme .chr_absence-work-pattern__work-pattern-listing{display:inline-block}#bootstrap-theme .chr_absence-work-pattern__alert{margin-bottom:0 !important}#bootstrap-theme .annual-entitlement-change-log-component thead td{min-width:100px}#bootstrap-theme .annual-entitlement-change-log-component thead .annual-entitlement-change-log-component__comments{min-width:300px}#bootstrap-theme .chr_annual-entitlements__period{width:130px}#bootstrap-theme .chr_annual-entitlements__edit-entitlements{width:150px}#bootstrap-theme .chr_contract-entitlements__position{width:140px}@media (max-width: 992px){#bootstrap-theme .chr_leave-balance-tab .chr_leave-balance-tab__filter:not(:last-child){padding-bottom:15px}}#bootstrap-theme .chr_leave-balance-tab__body{padding:0}#bootstrap-theme .chr_leave-calendar__dates-container{overflow-x:auto}@media (min-width: 1200px){#bootstrap-theme .chr_leave-calendar__dates-container .chr_leave-calendar{table-layout:fixed}}#bootstrap-theme .chr_leave-calendar__names-container .chr_leave-calendar{table-layout:fixed}#bootstrap-theme .chr_leave-calendar__day{font-size:10px !important;line-height:1.4em !important;padding:10px !important;text-align:center !important}@media (min-width: 1200px){#bootstrap-theme .chr_leave-calendar__day{padding:10px 0 !important}}#bootstrap-theme .chr_leave-calendar__day--disabled{opacity:0.5}#bootstrap-theme .chr_leave-calendar__day--current{color:#0071bd !important}#bootstrap-theme .chr_leave-calendar__item{color:#fff;display:block;font-size:10px;height:100%;position:relative;text-align:center;text-transform:uppercase;width:100%}#bootstrap-theme .chr_leave-calendar__item>span{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;height:1.2em}#bootstrap-theme .chr_leave-calendar__item>.chr_leave-calendar__time-unit{font-size:7px;height:1em;margin-left:-1px}#bootstrap-theme .chr_leave-calendar__item>a{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0;cursor:pointer}#bootstrap-theme .chr_leave-calendar__item--half{height:50%}#bootstrap-theme .chr_leave-calendar__item--half:not(:first-child){height:calc(50% - 1px);margin-top:1px}#bootstrap-theme .chr_leave-calendar__item--more{border:2px solid #d3dee2}#bootstrap-theme .chr_leave-calendar__item--more .chr_leave-calendar__item__label{color:#4d4d69}#bootstrap-theme .chr_leave-calendar__item--disabled{cursor:not-allowed;opacity:0.5}#bootstrap-theme .chr_leave-calendar__item--type--late{background-color:#eca67e;border-color:#eca67e}#bootstrap-theme .chr_leave-calendar__day-container--type--non-working{background-color:#41afcb}#bootstrap-theme .chr_leave-calendar__day-container--type--public-holiday{background-color:#8ec68a}#bootstrap-theme .chr_leave-calendar__day-container--type--weekend{background-color:#c7cbd0}#bootstrap-theme .chr_leave-calendar__item--alt{background-color:#fff !important;border:1px solid transparent;color:#464354}#bootstrap-theme .chr_leave-calendar__item--requested{background:repeating-linear-gradient(45deg, rgba(255,255,255,0.3), rgba(255,255,255,0.3) 5px, transparent 5px, transparent 8px)}#bootstrap-theme .chr_leave-calendar__item--requested.chr_leave-calendar__item--alt{background:repeating-linear-gradient(45deg, rgba(0,0,0,0.1), rgba(0,0,0,0.1) 5px, transparent 5px, transparent 8px)}#bootstrap-theme .chr_leave-calendar__items>td{height:35px;overflow:hidden}#bootstrap-theme .chr_leave-calendar__items .chr_leave-calendar__items_day-cell{padding:0 !important}#bootstrap-theme .chr_leave-calendar__items leave-calendar-day{display:block;height:100%}#bootstrap-theme .chr_leave-calendar__day-container{height:100%}#bootstrap-theme .chr_leave-calendar__legend__title{font-size:12px}#bootstrap-theme .chr_leave-calendar__legend>.row:not(:first-child){margin-top:20px}#bootstrap-theme .chr_leave-calendar__legend .chr_leave-calendar__legend__entry{margin-top:10px}@media (min-width: 768px){#bootstrap-theme .chr_leave-calendar__legend .chr_leave-calendar__legend__entry{margin-top:0}}#bootstrap-theme .chr_leave-calendar__legend__entry{overflow:auto}#bootstrap-theme .chr_leave-calendar__legend__entry+#bootstrap-theme .chr_leave-calendar__legend__entry{margin-top:10px}#bootstrap-theme .chr_leave-calendar__legend__entry>.chr_leave-calendar__item{font-size:8px;height:20px;margin-right:10px;position:absolute;width:20px}#bootstrap-theme .chr_leave-calendar__legend__label{display:inline-block;font-size:12px;margin-left:26px}#bootstrap-theme .chr_leave-calendar__month-header{background:#f3f6f7}#bootstrap-theme .chr_leave-calendar__month-header .panel-title{font-size:16px}#bootstrap-theme .chr_leave-calendar__name{font-size:12px !important;line-height:100%;padding:0 20px !important;text-align:left;text-overflow:ellipsis;width:100%}#bootstrap-theme .chr_leave-calendar__name_header,#bootstrap-theme .chr_leave-calendar__day{height:49px}#bootstrap-theme .chr_leave-calendar__name_header{padding-bottom:10px !important}#bootstrap-theme .chr_leave-calendar__name_cell{vertical-align:middle !important}#bootstrap-theme .chr_leave-calendar__pagination{font-size:10px;text-align:center}#bootstrap-theme .chr_leave-calendar__pagination [class*='btn']{line-height:1em;outline:none;padding:0}#bootstrap-theme .chr_leave-calendar__pagination [class*='btn'] .fa{color:#555}#bootstrap-theme .chr_leave-calendar__pagination [class*='btn'][disabled] .fa{opacity:0.5}#bootstrap-theme .chr_leave-calendar__pagination [class*='btn']:hover:not([disabled]) .fa{color:#464354}#bootstrap-theme .chr_leave-calendar__pagination-next{border-top:0}#bootstrap-theme .chr_leave-calendar__pagination-next th{height:24px;padding:4px 0 6px !important}#bootstrap-theme .chr_leave-calendar__pagination-next .chr_leave-calendar__pagination{padding-right:3px !important}#bootstrap-theme .chr_leave-calendar__month-container{margin:0}#bootstrap-theme .chr_leave-calendar__month-container>div{padding:0}#bootstrap-theme .chr_leave-calendar__admin-filters-hint{display:inline-block;font-size:20px;vertical-align:middle}#bootstrap-theme .chr_leave-calendar__admin-filters-select{display:inline-block;margin-right:20px;width:calc(100% - 50px)}#bootstrap-theme .chr_leave-report .dropdown-toggle{color:#464354;padding:0 10px}#bootstrap-theme .chr_leave-report .dropdown-toggle:hover{background:#e6e6e6}#bootstrap-theme .chr_leave-report table{table-layout:fixed}#bootstrap-theme .chr_leave-report table thead th,#bootstrap-theme .chr_leave-report table tbody td{padding:8px 5px}#bootstrap-theme .chr_leave-report__label{color:#464354;font-weight:700}#bootstrap-theme .chr_leave-report__label>.fa{margin-right:5px}#bootstrap-theme .chr_leave-report__label--toggle{cursor:pointer;user-select:none}#bootstrap-theme .chr_leave-report__heading{background-color:#f3f6f7;border-bottom:1px solid #dadcde}#bootstrap-theme .chr_leave-report__heading .chr_leave-report__export-button{line-height:2.4}#bootstrap-theme .chr_leave-report__table table,#bootstrap-theme .chr_leave-report__table .table{border-collapse:separate}#bootstrap-theme .chr_leave-report__table table>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>tbody>tr:first-child>td{border-top-width:0}#bootstrap-theme .chr_leave-report__table table>thead+tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>thead+tbody>tr:first-child>td{border-top-width:1px}#bootstrap-theme .chr_leave-report__table table:not(.table-bordered):not(.table-condensed)>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table:not(.table-bordered):not(.table-condensed)>tbody>tr:first-child>td{border-color:#f3f6f7}#bootstrap-theme .chr_leave-report__table table>thead>tr>th,#bootstrap-theme .chr_leave-report__table .table>thead>tr>th{background:#f3f6f7;border-bottom:0;color:#464354;text-transform:capitalize}#bootstrap-theme .chr_leave-report__table table>tbody>tr:first-child>td,#bootstrap-theme .chr_leave-report__table .table>tbody>tr:first-child>td{border-color:#e8eef0 !important}#bootstrap-theme .chr_leave-report__table table>tfoot>tr,#bootstrap-theme .chr_leave-report__table .table>tfoot>tr{background:#f3f6f7}#bootstrap-theme .chr_leave-report__table>table>thead>tr>th,#bootstrap-theme .chr_leave-report__table>.table>thead>tr>th{padding-bottom:13px;padding-top:13px}#bootstrap-theme .chr_leave-report__table-container{overflow:auto}#bootstrap-theme .chr_leave-report__table-container .panel{display:inline-block;min-width:100%}#bootstrap-theme .chr_leave-report__table__heading--action{width:45px}#bootstrap-theme .chr_leave-report__table__heading--label{width:280px}#bootstrap-theme .chr_leave-report__table__heading--dates{width:170px}#bootstrap-theme .chr_leave-report__table__heading--status{width:180px}#bootstrap-theme .chr_leave-report__table__heading--type{width:65px;word-break:break-word}#bootstrap-theme .chr_leave-request-comment{margin-top:10px}#bootstrap-theme .chr_leave-request-comment__text{border-bottom:1px solid #e8eef0;color:#c2cfd8;margin-right:10px;padding-bottom:20px}#bootstrap-theme .chr_leave-request-files_list{height:150px;overflow-y:auto;margin-top:20px;margin-bottom:20px}#bootstrap-theme .chr_leave-request-files_meta{margin-bottom:10px}#bootstrap-theme .chr_leave-request-files_upload{border:dashed 1px #464354;padding:20px}#bootstrap-theme .chr_leave-request-files_upload_action{padding:5px}#bootstrap-theme .chr_leave-request-files_file-name{display:inline-block;max-width:240px;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom}#bootstrap-theme .chr_leave-request-files_delete{margin-top:-7px}#bootstrap-theme .chr_leave-request-modal .modal-title{font-size:18px !important}#bootstrap-theme .chr_leave-request-modal .table-responsive{border:0}#bootstrap-theme .chr_leave-request-modal .chr_leave-request-date-picker-container .input-group{width:100%}@media screen and (max-width: 767px){#bootstrap-theme .chr_leave-request-modal .chr_leave-request-date-picker-container{margin-bottom:10px}}#bootstrap-theme .chr_leave-request-modal__chevron{font-size:0.6em;margin-right:5px;vertical-align:middle}#bootstrap-theme .chr_leave-request-modal__comments{height:230px;margin-bottom:20px;overflow:auto}#bootstrap-theme .chr_leave-request-modal__comments_empty{margin-bottom:20px}#bootstrap-theme .chr_leave-request-modal__footer{margin:0}#bootstrap-theme .chr_leave-request-modal__delete{margin-left:15px;margin-top:8px}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container{margin-bottom:20px}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container ul{opacity:1 !important}#bootstrap-theme .chr_leave-request-modal__form .ui-select-container:not(.ui-select-multiple) input{width:100% !important}#bootstrap-theme .chr_leave-request-modal__form-group,#bootstrap-theme .chr_leave-request-modal__required-documents>div{margin-bottom:15px}#bootstrap-theme .chr_leave-request-modal__response{padding:20px 20px 0}#bootstrap-theme .chr_leave-request-modal__response label{font-size:17px;margin-top:-3px}#bootstrap-theme .chr_leave-request-modal__response .chr_wysiwyg{margin-top:15px}#bootstrap-theme .chr_leave-request-modal__required-documents input{margin-right:5px}#bootstrap-theme .chr_leave-request-modal__small_spinner>div.chr_spinner{margin-top:18px;min-height:initial}#bootstrap-theme .chr_leave-request-modal__tab input[uib-datepicker-popup]{font-size:13px}#bootstrap-theme .chr_leave-request-modal__table{border:1px solid #f3f6f7;margin-bottom:15px !important}#bootstrap-theme .chr_leave-request-modal__user-info{font-size:17px;padding:20px}#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(1){color:#464354}#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(2){color:#555}@media screen and (min-width: 480px){#bootstrap-theme .chr_leave-request-modal__user-info>span:nth-child(2){border-left:1px solid #e8eef0}}#bootstrap-theme .chr_leave-request-modal__span-expiry{display:inline-block;margin-top:7px}#bootstrap-theme .chr_leave-request-modal__expiry-clear{position:absolute;right:3.5em;top:0.6em;z-index:2}#bootstrap-theme .chr_leave-request-modal__small-text{font-size:80%}#bootstrap-theme .chr_leave-request-modal__custom-deduction-toggling-row{margin-top:-5px}@media screen and (min-width: 768px){#bootstrap-theme .chr_leave-request-modal__custom-deduction-label{text-align:right}}@media screen and (max-width: 767px){#bootstrap-theme .chr_leave-request-modal__custom-deduction-label{margin-bottom:10px}}#bootstrap-theme .chr_leave-request-modal .form-group{overflow:inherit !important}#bootstrap-theme .chr_leave-request-modal .alert{margin-bottom:0 !important}#bootstrap-theme .chr_leave-request-modal input[uib-datepicker-popup]{box-shadow:none !important;background-color:inherit !important;color:inherit !important;cursor:pointer !important;border-right:none}#bootstrap-theme leave-request-record-actions{display:block}#bootstrap-theme leave-request-record-actions .btn-group{float:left}#bootstrap-theme leave-request-record-actions .btn-group:first-child{margin-right:8px}#bootstrap-theme leave-request-record-actions .btn-group:first-child .dropdown-menu{left:auto;right:0}@media screen and (max-width: 767px){#bootstrap-theme leave-request-record-actions .btn-group{width:calc((100% - 8px) / 2)}#bootstrap-theme leave-request-record-actions .btn{padding-left:0;padding-right:0;width:100%}#bootstrap-theme leave-request-record-actions .btn-group:first-child .dropdown-menu{left:0;right:auto}}#bootstrap-theme .leave-widget h4{color:#4d4d69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px}#bootstrap-theme .leave-widget__types>table,#bootstrap-theme .leave-widget__sickness>table,#bootstrap-theme .leave-widget__next-leave>table{border:none}#bootstrap-theme .leave-widget__types>table thead tr th,#bootstrap-theme .leave-widget__sickness>table thead tr th,#bootstrap-theme .leave-widget__next-leave>table thead tr th{color:#4d4d69;font-size:13px;font-weight:normal;margin-bottom:0;padding-bottom:13px;background:none;width:35%}#bootstrap-theme .leave-widget__types>table thead tr th:first-child,#bootstrap-theme .leave-widget__sickness>table thead tr th:first-child,#bootstrap-theme .leave-widget__next-leave>table thead tr th:first-child{width:65%}#bootstrap-theme .leave-widget__types>table tbody tr td,#bootstrap-theme .leave-widget__sickness>table tbody tr td,#bootstrap-theme .leave-widget__next-leave>table tbody tr td{color:#0071bd;font-size:16px;font-weight:600;padding-bottom:9px}#bootstrap-theme .leave-widget__types>table tbody tr td:first-child,#bootstrap-theme .leave-widget__sickness>table tbody tr td:first-child,#bootstrap-theme .leave-widget__next-leave>table tbody tr td:first-child{color:#464354}#bootstrap-theme .leave-widget hr{border-color:#DEE4ED;margin-bottom:25px;margin-top:25px}#bootstrap-theme .leave-widget__sickness h4{margin-top:18px}#bootstrap-theme .leave-widget__next-leave h3{font-size:16px;margin-bottom:16px;margin-top:0}#bootstrap-theme .leave-widget__next-leave__deduction{font-size:16px;font-weight:600;color:#464354}#bootstrap-theme .chr_leave__page-selector-dropdown{margin-right:5px;position:relative;top:1px;width:100%}#bootstrap-theme .chr_leave__page-selector-dropdown select{height:40px}#bootstrap-theme .chr_leave__page-selector-dropdown .crm_custom-select__arrow{line-height:40px;width:40px}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;border-bottom:1px solid #dadcde;margin:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header .panel-title{margin-top:7px;display:inline-block}@media screen and (max-width: 992px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header>div:not(:last-child),#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__header .panel-title{padding-bottom:20px}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter{display:inline-block;margin-top:7px;white-space:nowrap}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter .fa{font-size:0.6em;margin-right:5px;margin-top:-2px;vertical-align:middle}@media screen and (max-width: 991px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__filter{margin-top:15px}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;border-bottom:1px solid #dadcde;margin:0;padding-top:15px}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>*{padding-left:10px !important;padding-right:10px !important}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>div:not(:last-child){padding-bottom:20px}}@media screen and (min-width: 992px) and (max-width: 1199px){#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header>.no_gutter{padding-bottom:0 !important}}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body{margin:0;padding:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body [class^="col-"],#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body [class*=" col-"]{padding:0}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__panel_body a{cursor:pointer}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container{padding-left:10px;padding-right:10px;background-color:#f7f7f9}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__status_container>div{padding-left:15px;padding-right:15px}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .form-group{overflow:inherit !important}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .panel{background-image:none !important}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .panel-body,#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] .chr_vertical_tabs{background-color:#f7f7f9}#bootstrap-theme .chr_manage_leave_requests[data-role="admin"] input[type="search"]{width:100% !important}#bootstrap-theme .chr_manage_leave_requests .chr_manage_leave_requests__sub-header .checkbox{margin-top:5px}#bootstrap-theme .page-manager-leave .chr_manage_leave_requests .btn-sm{font-size:100% !important}#bootstrap-theme .chr_manager_calendar__header{padding-left:10px;padding-right:10px;padding-top:15px;margin:0;background-color:#f7f7f9;border-bottom:1px solid #dadcde}#bootstrap-theme .chr_manager_calendar__header>*{padding-left:10px !important;padding-right:10px !important}#bootstrap-theme .chr_manager_calendar__header .checkbox{margin:0}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manager_calendar__header>div:not(:last-child){padding-bottom:20px}}#bootstrap-theme .chr_manager_calendar__sub-header{padding-left:10px;padding-right:10px;background-color:#f7f7f9;margin:0}#bootstrap-theme .chr_manager_calendar__sub-header>*{padding-left:10px !important;padding-right:10px !important}@media screen and (max-width: 1199px){#bootstrap-theme .chr_manager_calendar__sub-header>div:not(:last-child){padding-bottom:20px}#bootstrap-theme .chr_manager_calendar__sub-header .ui-select-container{height:auto}}#bootstrap-theme .chr_leave-calendar__day-tooltip.tooltip.in{opacity:1}#bootstrap-theme .chr_leave-calendar__day-tooltip .tooltip-arrow{border-top-color:#fff !important}#bootstrap-theme .chr_leave-calendar__day-tooltip .tooltip-inner{background-color:#fff;border-radius:0;box-shadow:0 3px 8px 0 rgba(49,40,40,0.25);color:#464354;padding:0}#bootstrap-theme .chr_leave-calendar__day-tooltip_item{cursor:pointer;min-width:154px;padding:8px}#bootstrap-theme .chr_leave-calendar__day-tooltip_item:hover{background-color:#e8eef0}#bootstrap-theme .time-amount-picker .crm_custom-select{display:inline-block;margin-right:2px}#bootstrap-theme .time-amount-picker .crm_custom-select:nth-child(2){margin-left:10px}#bootstrap-theme .absence-tab-page .tab-pane{padding:0 !important}#bootstrap-theme .absence-tab-page .tab-content{background-color:transparent !important}#bootstrap-theme .absence-tab-page leave-request-record-actions{margin-bottom:20px}#bootstrap-theme .crm-absence_type-form-block .crm-section .label{width:35%}#bootstrap-theme .crm-absence_type-form-block .crm-section .content{margin-left:40%}#bootstrap-theme .crm-absence_type-form-block .toil-option,#bootstrap-theme .crm-absence_type-form-block .carry-forward-option,#bootstrap-theme .crm-absence_type-form-block .toil-expiration,#bootstrap-theme .crm-absence_type-form-block .carry-forward-expiration-duration,#bootstrap-theme .crm-absence_type-form-block .carry-forward-expiration-date{display:none}#bootstrap-theme .crm-absence_type-form-block .sp-replacer{padding:2px}#bootstrap-theme .crm-absence_type-form-block .sp-preview{height:15px;width:15px}#bootstrap-theme .crm-absence_type-form-block .sp-dd{height:0;line-height:15px;font-size:9px}.page-civicrm-leaveandabsences-dashboard .page-title,.page-civicrm-leaveandabsences-dashboard #branding{display:none !important}.page-civicrm-leaveandabsences-dashboard #page{margin:0;padding:0}.admin-dashboard-page{position:relative}.admin-dashboard-page .crm_page__topbar{height:65px}.admin-dashboard-page leave-request-record-actions{margin:12px 16px 0 0}.admin-dashboard-page .chr_admin-dashboard_side-nav{background-color:#fff;height:calc(100% - 12px);overflow:hidden;position:absolute;width:170px}.admin-dashboard-page .chr_admin-dashboard_side-nav .active{background:#e8eef0}.admin-dashboard-page .chr_admin-dashboard_content{float:right;margin:16px;margin-bottom:0;width:calc(100% - 170px - 16px * 2)}#bootstrap-theme #calculation-details{background:#fff}#bootstrap-theme #calculation-details .base-contractual-entitlement{color:#0071bd}#bootstrap-theme #calculation-details .working-days-to-work{color:#44cb7e}#bootstrap-theme #calculation-details .working-days-in-period{color:#e6ab5e}#bootstrap-theme #calculation-details .contract-1-pro-rata{color:#E6807F}#bootstrap-theme #calculation-details .contract-2-pro-rata{color:#797300}#bootstrap-theme #calculation-details .contract-3-pro-rata{color:#904E1E}#bootstrap-theme #calculation-details .contract-4-pro-rata{color:#0511B1}#bootstrap-theme #calculation-details .contract-5-pro-rata{color:#4B9609}#bootstrap-theme #calculation-details .calculation-pro-rata{color:#95c0ff}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body{padding-top:20px;padding-bottom:20px}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body .row:first-child h3{margin-top:0}#bootstrap-theme .crm-leave-and-absences-form-block .panel-body h3{margin-bottom:20px}#bootstrap-theme .crm-leave-and-absences-form-block .panel-footer .crm-button:last-child{margin-right:0}#bootstrap-theme.crm-leave-and-balance-import .panel{background-color:#fff}#bootstrap-theme.crm-leave-and-balance-import .panel-header{position:relative}#bootstrap-theme.crm-leave-and-balance-import .panel-header h2{padding:10px 20px}#bootstrap-theme.crm-leave-and-balance-import .panel-body .row:not(:last-child){padding-bottom:2em}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats .label{display:none}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats label{font-weight:normal !important}#bootstrap-theme.crm-leave-and-balance-import .table.date-formats td{border:0;padding:0}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block{box-shadow:none;padding:0}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table{margin-bottom:2em;width:100%}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table th{padding:10px 20px;border-right:none}#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table th,#bootstrap-theme.crm-leave-and-balance-import .crm-activity_map_table-form-block #map-field table td{padding:5px}#bootstrap-theme.crm-leave-and-balance-import #preview-counts,#bootstrap-theme.crm-leave-and-balance-import #summary-counts{box-shadow:none;margin-bottom:2em;width:100%}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td{background-color:#f2dede !important;color:#cf3458}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td a,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td a{color:#bd2d4e;font-weight:bold}#bootstrap-theme.crm-leave-and-balance-import #preview-counts tr.danger td a:hover,#bootstrap-theme.crm-leave-and-balance-import #summary-counts tr.danger td a:hover{color:#0062a4}#bootstrap-theme.manage-entitlements-form .wider-hr{margin-left:-20px;margin-right:-20px;border-width:2px}#bootstrap-theme.manage-entitlements-form .wider-row{margin-left:-20px;margin-right:-20px}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters{padding:15px 0;text-align:center}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .override-filters label{display:inline-block}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .override-filters label:before{display:none}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .absence-type-filter{margin-right:10px}#bootstrap-theme.manage-entitlements-form .entitlement-calculation-filters .col-sm-4:last-child{text-align:right}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list{margin-bottom:0}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement-header .title{float:left;width:65%}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement-header .actions{float:right}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list tr.hidden{display:none}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .absence-type{color:#fff;display:inline-block;padding:5px}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement .overridden-proposed-entitlement,#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .proposed-entitlement .calculation-unit{display:none}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .borderless-button{background-color:transparent;border:0;cursor:pointer}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .add-comment{font-size:1.1em}#bootstrap-theme.manage-entitlements-form .table.entitlement-calculation-list .comment-text{display:none}#bootstrap-theme.manage-entitlements-form .manage-entitlements-form__filters{padding-bottom:1em}#bootstrap-theme.manage-entitlements-form .table{background:#f9f9f9;border-top:1px solid #e8eef0;border-bottom:1px solid #e8eef0;margin-bottom:2em}#bootstrap-theme.manage-entitlements-form .table th{background:#f3f6f7 !important}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header{border-left:1px solid #e8eef0;border-right:1px solid #e8eef0;background:#e4ebed !important;min-width:200px}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .row>div{display:table-cell;float:none;vertical-align:bottom}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .fa{color:#4d4d69}#bootstrap-theme.manage-entitlements-form .table th.proposed-entitlement-header .action-button-container{padding:0}#bootstrap-theme.manage-entitlements-form .table td.proposed-entitlement{border-left:1px solid #e8eef0;border-right:1px solid #e8eef0;background:white}#bootstrap-theme.manage-entitlements-form .table span.absence-type{border-radius:3px;padding:0 5px}#bootstrap-theme.manage-entitlements-form .table tbody .fa{color:#0071bd}#bootstrap-theme.manage-entitlements-form .crm-container .CRM_HRLeaveAndAbsences_Form_ManageEntitlements .crm-button-type-next{float:right !important}#bootstrap-theme.manage-entitlements-form .panel-footer{border-top:none}#add-comment-dialog{display:none}#add-comment-dialog .calculation_comment{box-sizing:border-box;padding:10px;width:100%}#bootstrap-theme .crm-work-pattern-form-block .ui-tabs.ui-widget-content{background:none}#bootstrap-theme .work-pattern-calendar .number-of-weeks{padding:15px 0 15px 0}#bootstrap-theme .work-pattern-calendar .work-pattern-week{border-top:1px solid rgba(0,0,0,0.2);padding:15px 0 15px 0;margin-bottom:15px}#bootstrap-theme .work-pattern-calendar .work-pattern-week.hidden-week{display:none}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-number{float:left;font-weight:bold;padding:5px 0 15px 5px}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days{table-layout:fixed}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-hours{float:right;padding:5px 5px 15px 0}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-hours .number-of-hours{font-weight:bold}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days td{padding:5px 10px 5px 10px}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days input{min-width:0;text-align:center}#bootstrap-theme .work-pattern-calendar .work-pattern-week .week-days select{min-width:0;width:100% !important}#bootstrap-theme .work-pattern-calendar .work-pattern-week .hours-row td{padding-top:15px;padding-bottom:15px;border-top:1px solid rgba(0,0,0,0.2);border-bottom:1px solid rgba(0,0,0,0.2)}.chr_leave-calendar__day-tooltip.tooltip.in{opacity:1}.chr_leave-calendar__day-tooltip .tooltip-arrow{border-top-color:#fff !important}.chr_leave-calendar__day-tooltip .tooltip-inner{background-color:#fff;border-radius:0;box-shadow:0 3px 8px 0 rgba(49,40,40,0.25);color:#464354;padding:0}.chr_leave-calendar__day-tooltip_item{cursor:pointer;min-width:154px;padding:8px}.chr_leave-calendar__day-tooltip_item:hover{background-color:#e8eef0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:2px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.5384615385;color:#4d4d69;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#42425a;background-color:#f3f6f7}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#0071bd}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#e8eef0}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.5384615385;color:#464354;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{left:0;right:auto}}.dropdown-header{padding:11px 20px}.dropdown-menu{-webkit-box-shadow:0 3px 18px 0 rgba(48,40,40,0.25);box-shadow:0 3px 18px 0 rgba(48,40,40,0.25);border:0;margin:0;padding:0}.dropdown-menu>li{border:0;margin:0;padding:0}.dropdown-menu>li>a{padding:11px 20px} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/hrleaveandabsences.php b/uk.co.compucorp.civicrm.hrleaveandabsences/hrleaveandabsences.php index 6daf325bb43..162aad95f9e 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/hrleaveandabsences.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/hrleaveandabsences.php @@ -294,6 +294,12 @@ function hrleaveandabsences_civicrm_entityTypes(&$entityTypes) { 'class' => 'CRM_HRLeaveAndAbsences_DAO_LeavePeriodEntitlementLog', 'table' => 'civicrm_hrleaveandabsences_leave_period_entitlement_log', ]; + + $entityTypes[] = [ + 'name' => 'LeaveBalanceChangeExpiryLog', + 'class' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'table' => 'civicrm_hrleaveandabsences_leave_balance_change_expiry_log', + ]; } /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/info.xml b/uk.co.compucorp.civicrm.hrleaveandabsences/info.xml index 83f8ff97d3c..0045a44b075 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/info.xml +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/info.xml @@ -8,8 +8,8 @@ Compucorp Ltd info@compucorp.co.uk - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7 diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/absence-tab.min.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/absence-tab.min.js index 319ab39ee97..bcb8533926d 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/absence-tab.min.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/absence-tab.min.js @@ -1,5 +1,5 @@ -!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/modules/shared-settings",["common/angular"],function(t){return t.module("leave-absences.settings",[]).constant("shared-settings",{attachmentToken:e.vars.leaveAndAbsences.attachmentToken,debug:e.debug,managerPathTpl:e.vars.leaveAndAbsences.baseURL+"/views/manager-leave/",sharedPathTpl:e.vars.leaveAndAbsences.baseURL+"/views/shared/",serverDateFormat:"YYYY-MM-DD",serverDateTimeFormat:"YYYY-MM-DD HH:mm:ss",permissions:{admin:{access:"access leave and absences",administer:"administer leave and absences"},ssp:{access:"access leave and absences in ssp",manage:"manage leave and absences in ssp"}},fileUploader:{queueLimit:10},statusNames:{approved:"approved",adminApproved:"admin_approved",awaitingApproval:"awaiting_approval",moreInformationRequired:"more_information_required",rejected:"rejected",cancelled:"cancelled"}})})}(CRM),define("leave-absences/shared/modules/apis",["common/angular","common/modules/apis","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.apis",["common.apis","leave-absences.settings"])}),define("leave-absences/shared/modules/models-instances",["common/angular","common/models/instances/instance","common/modules/services","common/modules/models","common/services/check-permissions","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.models.instances",["common.models","common.models.instances","common.services","leave-absences.settings"])}),define("leave-absences/shared/modules/models",["common/angular","common/modules/models","common/modules/services","leave-absences/shared/modules/apis","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.models",["common.models","common.services","leave-absences.apis","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,o){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,s,r){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),r=e.assign({},r,{absence_type_id:a,date:t(s).format(o.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",r).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,o,s,r){return t.debug("AbsenceType"),a.extend({all:function(e){return s.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return s.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return s.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return o.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,o,s,r){return this.sendPOST("ContactWorkPattern","create",e.assign({},r,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:o,change_reason:s})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,o,s){return t.debug("WorkPatternAPI.getCalendar",n,a,o,s),this.sendGET("WorkPattern","getcalendar",e.assign({},s,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:o}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,o){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),o).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,o,s,r){function i(t,n){return u().then(function(a){var o=this.days[c(t).valueOf()];return!!o&&e.find(a,function(e){return e.name===n}).value===o.type}.bind(this))}function c(e){return t(e,s.serverDateFormat).clone()}function u(){return l=l||r.valuesOf("hrleaveandabsences_work_day_type")}var l;return o.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[c(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,o){return t.debug("Calendar"),n.extend({get:function(n,s,r,i){return t.debug("Calendar.get"),a.getCalendar(n,s,r,i).then(function(t){var a=t.values.map(function(e){return o.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,n){function a(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(n.remainder=a[0].remainder),delete n["api.LeavePeriodEntitlement.getremainder"],n}function o(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return n.value=a,delete n["api.LeavePeriodEntitlement.getentitlement"],n}return e.debug("EntitlementAPI"),n.extend({all:function(t,n){return e.debug("EntitlementAPI.all"),t["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},n&&(t["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",t,!1).then(function(e){return e.values}).then(function(e){return e=e.map(o),n&&(e=e.map(a)),e})},breakdown:function(t){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",t).then(function(e){return e.values})},getLeaveBalances:function(t,n,a,o,s){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",t,n,a,o,"getLeaveBalances",s)}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,o,s){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return o.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return o.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),s.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,o,s,r){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,o,s,"getFull",r)),i.promise},balanceChangeByAbsenceType:function(t,n,o,s){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var r=a.defer();t&&n||r.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:o?{IN:o}:null,public_holiday:s||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){r.resolve(e.values)}),r.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var o=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?o.reject(t(e.values).map().flatten().value()):o.resolve(e.values)}),o.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,o,s,r,i,c){function u(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return c.all({id:this.type_id}).then(c.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function m(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function f(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return o.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),o=a.breakdown.length>1,s=e.first(e.values(a.breakdown)),r=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(s.date),o&&this.getWorkDayForDate(r.date)]).then(function(t){return s.amount=t[0].time_from?Math.min(this.from_date_amount,f(t[0])):0,o&&(r.amount=t[1].time_from?Math.min(this.to_date_amount,f(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return r.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return u.call(this,s.statusNames.cancelled)},approve:function(){return u.call(this,s.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return u.call(this,s.statusNames.rejected)},sendBack:function(){return u.call(this,s.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),m.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,s.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,s.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,s.statusNames.cancelled)},isRejected:function(){return d.call(this,s.statusNames.rejected)},isSentBack:function(){return d.call(this,s.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(s.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,o,s,r){return n.all(this.processFilters(e),t,o,s,r).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,o){return n.balanceChangeByAbsenceType(e,t,a,o)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/instances/work-pattern.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("WorkPatternInstance",["$log","ModelInstance",function(e,t){return e.debug("WorkPatternInstance"),t.extend({})}])}),define("leave-absences/shared/models/work-pattern.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/work-pattern.instance"],function(e,t){"use strict";t.factory("WorkPattern",["$log","Model","WorkPatternAPI","WorkPatternInstance",function(t,n,a,o){return t.debug("WorkPattern"),n.extend({assignWorkPattern:function(e,t,n,o,s,r){return a.assignWorkPattern(e,t,n,o,s,r)},default:function(){return a.get({is_default:!0}).then(function(t){return o.init(e.first(t),!0)})},unassignWorkPattern:function(e){return a.unassignWorkPattern(e)},workPatternsOf:function(e,t,n){return a.workPatternsOf(e,t,n).then(function(e){return e.map(function(e){return o.init(e,!0)})})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,t,n){function a(n,a,o,s,r,i){function c(){return d().then(function(n){var a=n.filter(function(e){var n=e.info.details;return t(n.period_start_date).isSameOrBefore(v.selectedPeriod.end_date)&&(t(n.period_end_date).isSameOrAfter(v.selectedPeriod.start_date)||!n.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function u(){return{loadContacts:function(){var e=v.filters.userSettings.assignedTo.type;return m(e).then(function(e){v.lookupContacts=e}).then(function(){return"me"!==e?c():a.resolve(null)}).then(function(e){return v.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return o.all(f(),null,"display_name").then(function(e){return e.list})}function d(){return h?a.resolve(h):r.all()}function m(e){return"me"===e?o.leaveManagees(v.contactId):"unassigned"===e?o.leaveManagees(void 0,{unassigned:!0}):o.all().then(function(e){return e.list})}function f(){return{department:v.filters.userSettings.department?v.filters.userSettings.department.value:null,level_type:v.filters.userSettings.level_type?v.filters.userSettings.level_type.value:null,location:v.filters.userSettings.location?v.filters.userSettings.location.value:null,region:v.filters.userSettings.region?v.filters.userSettings.region.value:null,id:{IN:v.filters.userSettings.contact?[v.filters.userSettings.contact.id]:v.lookupContacts.map(function(e){return e.id})}}}function p(e){i.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,u()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:r.contactId}).leaveManagees().then(function(e){r.lookupContacts=e}).then(o)}}}function o(){return t.all(s(),null,"display_name").then(function(e){return e.list})}function s(){return{department:r.filters.userSettings.department?r.filters.userSettings.department.value:null,level_type:r.filters.userSettings.level_type?r.filters.userSettings.level_type.value:null,location:r.filters.userSettings.location?r.filters.userSettings.location.value:null,region:r.filters.userSettings.region?r.filters.userSettings.region.value:null,id:{IN:r.filters.userSettings.contact?[r.filters.userSettings.contact.id]:r.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var r;return{init:function(e){return r=e,r.showContactName=!0,r.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function o(a,o,s,r,i,c,u,l,d,m){function f(){for(var e=[],t=n(O.selectedPeriod.start_date).clone().startOf("month"),a=n(O.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(A(t)),t.add(1,"month");O.months=e}function p(){r.$new().$watch(function(){return O.selectedMonths},function(t,n){null===n||e.equals(t,n)||w()})}function h(e){O.injectMonths=!0,L("injected").then(function(){w(e)}).then(function(){O.loading.calendar=!1})}function v(){S=a("LeaveCalendar"+t.capitalize(M)+"Controller").init(O)}function b(e){return e.current?"Current Period ("+e.title+")":e.title}function g(){return c.all().then(function(e){O.absencePeriods=t.sortBy(e,"start_date"),O.selectedPeriod=t.find(O.absencePeriods,function(e){return!!e.current})}).then(f).then(I)}function _(){return u.all().then(u.loadCalculationUnits)}function y(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return S.loadContacts().then(function(e){O.contacts=e})}function C(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){O.filters.optionValues.regions=e.hrjc_region,O.filters.optionValues.locations=e.hrjc_location,O.filters.optionValues.levelTypes=e.hrjc_level_type,O.filters.optionValues.departments=e.hrjc_department})}function P(){return l.all()}function D(){return o.all([_(),P(),y()]).then(function(e){O.supportData.absenceTypes=e[0],O.supportData.publicHolidays=e[1],O.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,O.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,O.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,O.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function R(){var e=o.resolve();return O.injectMonths&&(e=L("destroyed"),O.injectMonths=!1),e}function A(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function T(e){e=t.includes(["contacts","period"],e)?e:"period",o.resolve().then(function(){O.loading.calendar=!0}).then(R).then("period"===e?f:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function w(e){var n=O.selectedMonths.length?O.months.filter(function(e){return t.includes(O.selectedMonths,e.index)}):O.months;r.$emit("LeaveCalendar::showMonths",n,!!e)}function I(){O.selectedMonths=[n().month()]}function k(){return O.roleOverride?o.resolve().then(function(){M=O.roleOverride}):o.all([m(i.permissions.admin.administer),m(i.permissions.ssp.manage)]).then(function(e){M=e[0]?"admin":e[1]?"manager":"staff"})}function L(e){return o(function(n){var a=0,o=r.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===O.months.length&&(o(),n())})})}s.debug("Component: leave-calendar");var S,M,O=this;O.absencePeriods=[],O.contacts=[],O.contactIdsToReduceTo=null,O.injectMonths=!1,O.months=[],O.selectedMonths=null,O.selectedPeriod=null,O.showContactName=!1,O.showFilters=!1,O.supportData={},O.loading={calendar:!0,page:!0},O.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},O.labelPeriod=b,O.refresh=T,function(){k().then(p).then(v).then(R).then(g).then(function(){return o.all([q(),D()])}).then(function(){return O.showFilters?C():t.noop}).then(function(){h()}).then(function(){O.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",o]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,o){"use strict";function s(){y.calculationUnit=r(y.supportData.calculationUnits,"value",b.calculation_unit)}function r(t,n,a){return e.find(t,function(e){return+e[n]==+a})}function i(){var e,n;return n=t(y.contactData.leaveRequest.from_date).isSame(y.contactData.leaveRequest.to_date,"day"),e=n?"single-date":"multiple-dates","type-"+y.calculationUnit.name+"-on-"+e+"-tooltip"}function c(){b=r(y.supportData.absenceTypes,"id",y.contactData.leaveRequest.type_id),y.contactData.leaveRequest["type_id.title"]=b.title}function u(){"days"===y.calculationUnit.name&&(g=r(y.supportData.dayTypes,"value",y.contactData.leaveRequest.from_date_type),_=r(y.supportData.dayTypes,"value",y.contactData.leaveRequest.to_date_type),y.contactData.leaveRequest["from_date_type.label"]=g.label,y.contactData.leaveRequest["to_date_type.label"]=_.label)}function l(e,t,n,a,s){e.stopPropagation(),o.openModal(t,n,a,s)}function d(){y.dates.from=new Date(y.contactData.leaveRequest.from_date),y.dates.to=new Date(y.contactData.leaveRequest.to_date)}function m(){y.contactData.isAccruedTOIL?y.label="AT":"days"===y.calculationUnit.name?f():p()}function f(){y.label=y.contactData.isAM?"AM":y.contactData.isPM?"PM":""}function p(){var e=t(y.contactData.leaveRequest.from_date).isSame(y.date,"day"),n=t(y.contactData.leaveRequest.to_date).isSame(y.date,"day");y.label=e?t(y.contactData.leaveRequest.from_date).format("HH:mm"):n?t(y.contactData.leaveRequest.to_date).format("HH:mm"):""}function h(){y.tooltipTemplate=y.contactData.isAccruedTOIL?"accrued-toil-tooltip":i()}function v(){a.$watch("day.contactData.leaveRequest",function(){y.contactData&&y.contactData.leaveRequest&&(c(),s(),u(),m(),d(),h()) -})}n.debug("Component: leave-calendar-day");var b,g,_,y=this;y.calculationUnit="",y.dates={from:null,to:null},y.label="",y.tooltipTemplate=null,y.openLeavePopup=l,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,o,s,r,i,c){function u(e){_([e]),N(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),o=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:o.format("YYYY-MM-DD"),name:o.format("ddd"),index:o.format("D"),current:a.isSame(o,"day"),enabled:o.isSameOrAfter(H.period.start_date)&&o.isSameOrBefore(H.period.end_date),contactsData:{}};return o.add(1,"day"),e})}function m(e){return U[e]}function f(){return H.showOnlyWithLeaveRequests?H.contacts.filter(function(e){return Object.keys(W[e.id]||{}).length}):H.contacts}function p(e){return t(e,c.serverDateFormat)}function h(e){S(e),N(e)}function v(e){return CRM.url("civicrm/contact/view",{cid:e})}function b(){return H.contactIdsToReduceTo&&(H.contacts=H.contacts.filter(function(t){return e.includes(H.contactIdsToReduceTo,t.contact_id)||e.find(W,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function g(){H.supportData.dayTypes=e.indexBy(H.supportData.dayTypes,"name"),H.supportData.leaveRequestStatuses=e.indexBy(H.supportData.leaveRequestStatuses,"value"),H.supportData.publicHolidays=e.transform(H.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function _(e){return e.forEach(function(e){var t=R(e);W[e.contact_id]=W[e.contact_id]||{},t.forEach(function(t){W[e.contact_id][t.date]=e})}),a.resolve()}function y(){F.push(o.$on("LeaveCalendar::showMonths",x)),F.push(i.subscribe("LeaveRequest::new",u)),F.push(i.subscribe("LeaveRequest::edit",B)),F.push(i.subscribe("LeaveRequest::updatedByManager",B)),F.push(i.subscribe("LeaveRequest::delete",h)),F.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):B(e.leaveRequest)}))}function q(e,n,a){var o=H.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?o.value===n.from_date_type:t(a).isSame(n.to_date,"day")?o.value===n.to_date_type:void 0}function C(e,t){return e.request_type===t}function P(e){return!!H.supportData.publicHolidays[p(e).valueOf()]}function D(t){var n=H.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([c.statusNames.awaitingApproval,c.statusNames.moreInformationRequired],n)}function R(n){for(var a=[],o=t(n.from_date).clone(),s=t(n.to_date);o.isSameOrBefore(s);)o.month()===H.month.index&&o.year()===H.month.year&&a.push(e.find(H.month.days,function(e){return e.date===o.format("YYYY-MM-DD")})),o.add(1,"day");return a}function A(t){return e.find(W[t.contact_id],function(e){return t.id===e.id})}function T(t){var n=e.find(H.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function w(){return[T(c.statusNames.approved),T(c.statusNames.adminApproved),T(c.statusNames.awaitingApproval),T(c.statusNames.moreInformationRequired)]}function I(){return H.month.loading=!0,a.all([L(),k()]).then(b).then($).then(function(){j=!0}).then(function(){H.month.loading=!1})}function k(){return r.all({from_date:{to:H.month.days[H.month.days.length-1].date},to_date:{from:H.month.days[0].date},status_id:{IN:w()},contact_id:{IN:H.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(H.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return _(e.list)})}function L(){var t=H.month.days[0].date,n=H.month.days[H.month.days.length-1].date;return s.get(H.contacts.map(function(e){return e.id}),t,n).then(function(t){U=e.indexBy(t,"contact_id")})}function S(t){W[t.contact_id]=e.omit(W[t.contact_id],function(e){return e.id===t.id})}function M(){o.$emit("LeaveCalendar::monthDestroyed"),F.map(function(e){e.remove?e.remove():e()})}function O(t,n,o){var s,r;return t.contactsData[n]=t.contactsData[n]||{},r=m(n),s=!0===o?a.resolve():a.all([r.isWeekend(p(t.date)),r.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:P(t.date)})}),s.then(function(){return W[n]?W[n][t.date]:null}).then(function(a){e.assign(t.contactsData[n],{leaveRequest:a||null,styles:a?E(a):null,isAccruedTOIL:a?C(a,"toil"):null,isRequested:a?D(a):null,isAM:a?q("half_day_am",a,t.date):null,isPM:a?q("half_day_pm",a,t.date):null})})}function $(){return a.all(H.month.days.map(function(e){return a.all(H.contacts.map(function(t){return O(e,t.id)}))}))}function x(t,n,a){!e.find(n,function(e){return e.index===H.month.index})?H.visible=!1:(H.currentPage=0,H.visible=!0,(a||!j)&&I())}function E(t){var n=e.find(H.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function B(e){var t=A(e);t&&(h(t),-1!==w().indexOf(e.status_id)&&u(e))}function N(e){return a.all(R(e).map(function(t){return O(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var j=!1,F=[],U={},W={},H=this;H.currentPage=0,H.pageSize=20,H.visible=!1,H.showContactName=!!H.showContactName,H.showOnlyWithLeaveRequests=!!H.showOnlyWithLeaveRequests,H.$onDestroy=M,H.contactsList=f,H.getContactUrl=v,function(){var e=t().month(H.month.index).year(H.month.year);g(),y(),H.month=l(e),o.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function o(){var t=n.defer();return a.open(e.defaults(s(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function s(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:s,promptBalanceChangeRecalculation:o}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,o,s,r,i,c,u){function l(t){y=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?o.open(h(t)):f(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function m(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||!!e.includes([C.awaitingApproval,C.moreInformationRequired],n)&&("manager"===q.role||("3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a))}function f(t){o.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(r.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){s.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=P[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){b(e)}).catch(function(e){u.error("Error:",e)})}}}function v(e,t,n,a,o){e.stopPropagation(),s.openModal(t,n,a,o)}function b(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===c.statusNames.awaitingApproval}).value;y===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function g(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(P,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!m(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&_(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:P[e].label,isDirectAction:P[e].isDirectAction}})}function _(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var y,q=this,C=c.statusNames,P={edit:{label:"Edit",allowedStatuses:[C.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[C.moreInformationRequired]},view:{label:"View",allowedStatuses:[C.approved,C.rejected,C.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[C.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[C.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[C.awaitingApproval,C.approved,C.rejected,C.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[C.awaitingApproval,C.moreInformationRequired,C.approved,C.rejected,C.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),g()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,o,s,r,i,c){function u(){q.request.comments.push({contact_id:y,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function m(e){return t.utc(e,r.serverDateTimeFormat).local().format(s.DATE_FORMAT.toUpperCase()+" HH:mm")}function f(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===y?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function b(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function g(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&b()})}function _(){return q.loading.component=!0,c.get().then(function(e){y=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var y=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=u,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=m,q.getActiveComments=f,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){o.$emit("LeaveRequestPopup::addTab",q),g(),_()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,o,s,r,i,c,u,l,d,m,f){function p(){pe.balance.closing=pe.balance.opening+pe.balance.change.amount}function h(e){return t(e,c.serverDateFormat).toDate()}function v(e){return t(e).format(c.serverDateFormat)}function b(e){var t;return r.resolve().then(function(){J(e),"from"===e&&Q(),N("hours")&&(y(e),"from"!==e||pe.uiOptions.multipleDays||y("to")),pe.loading[e+"DayTypes"]=!0}).then(pe.onDateChangeExtended).then(function(){return P(e)}).then(function(e){if(t=e.id!==pe.period.id,t&&(pe.period=e),!pe.period.id)return r.reject("Please change date as it is not in any absence period")}).then(Z).then(function(){if(t)return G()}).then(function(){return U(pe.uiOptions[e+"Date"],e)}).then(function(){if(N("hours"))return H(e).then(function(){ne(e,!0)})}).then(function(){if(se(),!t)return V();o.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(I)}function g(){return se(),V()}function _(){return pe.uiOptions.toDate=null,J("to"),r.resolve().then(function(){if(N("hours")&&pe.uiOptions.fromDate)return y("from"),!pe.uiOptions.multipleDays&&y("to"),H("from").then(function(){ne("from",!0)}).then(se)}).then(pe.setDaysSelectionModeExtended).then(!pe.uiOptions.multipleDays&&V)}function y(e){var t=pe.uiOptions.times[e];t.loading=!0,t.disabled=!0}function q(t,n){var a=pe.uiOptions.times[t],o=e.clone(n.time_from),s=e.clone(n.time_to);pe.uiOptions.multipleDays||("from"===t&&s&&o&&(s=A(s).subtract(pe.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&o&&s&&(o=A(o).add(pe.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=o||"00:00",a.max=s||"00:00",a.time="to"===t?a.max:a.min,a.disabled=!1}function C(t,n){return t?(t=v(t),d.isPublicHoliday(t).then(function(n){return n?pe.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):D(t,pe.requestDayTypes).then(function(t){return t.length?t:pe.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return te(n,e),e})):r.reject([])}function P(n){var a=t(pe.uiOptions[n+"Date"]).format(pe.uiOptions.userDateFormat.toUpperCase());return e.find(pe.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function D(e,n){return e=t(e),r.all([pe.calendar.isNonWorkingDay(e),pe.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function R(){return pe.request?pe.request.request_type:pe.leaveType||null}function A(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function T(){return ie(),pe.loading.balanceChange=!0,pe.request.getBalanceChangeBreakdown().then(K).catch(I)}function w(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function I(t){o.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),pe.loading.fromDayTypes=!1,pe.loading.balanceChange=!1,pe.loading.tab=!1,pe.loading.toDayTypes=!1}function k(){return pe.isMode("create")||pe.forceRecalculateBalanceChange?V():T()}function L(){var e=pe.request.attributes();return pe.uiOptions.fromDate=h(pe.request.from_date),U(pe.uiOptions.fromDate,"from").then(function(){return pe.request.to_date=e.to_date,pe.request.to_date_type=e.to_date_type,pe.uiOptions.toDate=h(pe.request.to_date),U(pe.uiOptions.toDate,"to")})}function S(e){s.$watch("detailsTab.uiOptions.times."+e+".amount",function(e,t){N("days")||+e==+t||(re(),pe.performBalanceChangeCalculation())})}function M(){fe.push(o.$on("LeaveRequestPopup::absenceTypeChanged",function(){ue()}),o.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){le(t)}),o.$on("LeaveRequestPopup::recalculateBalanceChange",V))}function O(){pe.isMode("edit")&&(pe.isLeaveStatus(c.statusNames.approved)||pe.isLeaveStatus(c.statusNames.adminApproved))&&(me={absenceTypeId:pe.request.type_id,value:pe.selectedAbsenceType.remainder-pe.request.balance_change})}function $(e){var n=t(pe.request[e+"_date"]).format("HH:mm"),a=pe.uiOptions.times[e];(w(a.min,n)<=0||w(a.max,n)>=0)&&(n="from"===e?a.min:a.max),pe.uiOptions.times[e].time=n}function x(){var e=pe.uiOptions.multipleDays?["from","to"]:["from"],t=pe.uiOptions.times;return r.all(e.map(H)).then(function(){["from","to"].forEach(function(e){$(e),ne(e),t[e].amount=Math.min(pe.request[e+"_date_amount"],t[e].maxAmount).toString()}),pe.uiOptions.multipleDays||de(pe.uiOptions.times.from.time)}).then(re)}function E(){["from","to"].forEach(function(e){S(e),B(e)})}function B(e){s.$watch("detailsTab.uiOptions.times."+e+".time",function(t,n){N("days")||t===n||(se(),t&&(!pe.uiOptions.multipleDays&&"from"===e&&de(t),ne(e,!0)))})}function N(e){return pe.selectedAbsenceType.calculation_unit_name===e}function j(e){return pe.request.request_type===e}function F(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function U(e,t){return C(e,t).then(function(){pe.loading[t+"DayTypes"]=!1})}function W(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){pe.requestDayTypes=e})}function H(e){var t=pe.uiOptions[e+"Date"],n=pe.uiOptions.times[e],a=!pe.uiOptions.multipleDays;return t?pe.request.getWorkDayForDate(v(t)).then(function(t){he[e]=t,q(e,t),a&&"from"===e&&q("to",t)}).catch(function(t){return he[e]={},I(t)}).finally(function(){n.loading=!1,a&&(pe.uiOptions.times.to.loading=!1)}):r.resolve()}function G(){return u.get(pe.request.contact_id,pe.period.start_date,pe.period.end_date).then(function(e){pe.calendar=e})}function Y(){var e=(pe.pagination.currentPage-1)*pe.pagination.numPerPage,t=e+pe.pagination.numPerPage;pe.pagination.filteredbreakdown=pe.balance.change.breakdown.slice(e,t)}function V(){return ie(),pe.canCalculateChange()?(pe.loading.balanceChange=!0,pe.request.change_balance=!0,pe.calculateBalanceChange().then(K).catch(I).finally(function(){pe.loading.balanceChange=!1})):r.resolve()}function z(){pe.pagination.totalItems=pe.balance.change.breakdown.length,pe.pagination.filteredbreakdown=pe.balance.change.breakdown,pe.pagination.pageChanged()}function X(){return v(pe.request.from_date)===v(pe.request.to_date)}function Q(){pe.uiOptions.toDate&&pe.uiOptions.fromDate&&pe.uiOptions.multipleDays&&t(pe.uiOptions.toDate).isSameOrBefore(pe.uiOptions.fromDate)&&(pe.uiOptions.toDate=null,J("to"))}function J(t){var n=pe.uiOptions.times[t];pe["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0",n.loading=!1,se(),re(),ie()}function K(e){pe.balance.change=e,pe.request.balance_change=e.amount,p(),z(),pe.loading.balanceChange=!1}function Z(){var e,n,a;pe.uiOptions.fromDate?(e=t(pe.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=h(pe.period.start_date),n=pe.uiOptions.date.to.options.minDate),pe.uiOptions.date.to.options.initDate=n,pe.uiOptions.date.to.options.minDate=a,pe.uiOptions.date.to.options.maxDate=h(pe.period.end_date)}function ee(){return!pe.isMode("create")&&X()||pe.isMode("create")&&(j("sickness")||N("hours"))?pe.uiOptions.multipleDays=!1:pe.uiOptions.multipleDays=!0,r.resolve().then(pe.setDaysSelectionModeExtended)}function te(t,n){var a="request"+e.startCase(t)+"DayTypes";pe[a]=n,pe.isMode("create")&&(pe.request[t+"_date_type"]=pe[a][0].value)}function ne(e,t){var n=pe.uiOptions,a=n.multipleDays?e:"from",o=n.times[a],s=n.multipleDays&&"to"===a?o.min:n.times.from.time,r=n.multipleDays&&"from"===a?o.max:n.times.to.time,i=he[a].number_of_hours?w(s,r).toString():"0";o.maxAmount=i,t&&(o.amount=o.maxAmount)}function ae(){me&&me.absenceTypeId===pe.selectedAbsenceType.id?pe.balance.opening=me.value||0:pe.balance.opening=pe.selectedAbsenceType.remainder}function oe(){pe.selectedAbsenceType=e.find(pe.absenceTypes,function(e){return e.id===pe.request.type_id})}function se(){var e=pe.uiOptions,t=e.times;pe.request.from_date=e.fromDate?v(e.fromDate):null,pe.request.to_date=e.toDate?v(e.toDate):null,!e.multipleDays&&e.fromDate&&(pe.request.to_date=pe.request.from_date,pe.request.to_date_type=pe.request.from_date_type),N("hours")&&!j("toil")&&(pe.request.from_date=pe.request.from_date&&t.from.time?pe.request.from_date+" "+t.from.time:null,pe.request.to_date=pe.request.to_date&&t.to.time?pe.request.to_date+" "+t.to.time:null)}function re(){var e=pe.uiOptions.times;pe.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,pe.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function ie(){pe.uiOptions.showBalance=pe.canCalculateChange()}function ce(){e.forEach(fe,function(e){e()})}function ue(){var e,t=pe.selectedAbsenceType.calculation_unit_name;return oe(),e=t!==pe.selectedAbsenceType.calculation_unit_name,ae(),r.resolve().then(e&&ee).then(function(){if(e&&N("hours"))return H("from").then(function(){ne("from",!0)})}).then(e&&se).then(V)}function le(e){return pe.absenceTypes=e,oe(),t(pe.uiOptions.toDate).isAfter(pe.period.end_date)&&(pe.uiOptions.toDate=void 0,J("to")),ae(),V()}function de(e){var t=A(e).add(pe.uiOptions.time_interval,"minutes");t.isAfter(A(pe.uiOptions.times.to.max))||(pe.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(A(pe.uiOptions.times.to.time))&&(pe.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var me=null,fe=[],pe=this,he={};pe.canManage=!1,pe.calendar={},pe.errors=[],pe.isRequired=!0,pe.requestDayTypes=[],pe.statusNames=c.statusNames,pe.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},pe.pagination={currentPage:1,filteredbreakdown:pe.balance.change.breakdown,numPerPage:7,totalItems:pe.balance.change.breakdown.length,pageChanged:Y},pe.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},pe.convertDateFormatFromServer=h,pe.convertDateToServerFormat=v,pe.dateChangeHandler=b,pe.dateTypeChangeHandler=g,pe.daysSelectionModeChangeHandler=_,pe.isLeaveType=j,pe.isNotWorkingDay=F,pe.performBalanceChangeCalculation=V,pe.$onDestroy=ce,function(){n("RequestModalDetails"+e.capitalize(R(pe.leaveType,pe.request))+"Controller",{detailsController:pe}),pe.canManage=pe.isRole("manager")||pe.isRole("admin"),pe.loading.tab=!0,s.$emit("LeaveRequestPopup::addTab",pe),M(),pe.initChildController().then(function(){return r.all([G(),W()])}).then(!pe.isMode("create")&&L).then(ee).then(function(){if(!pe.isMode("create")&&N("hours"))return x().then(se)}).then(!pe.isMode("create")&&Z).then(O).then(ae).then(k).then(function(){pe.isMode("view")||j("toil")||E()}).catch(I).finally(function(){pe.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","PublicHoliday","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,o,s,r,i,c,u,l){function d(){return k.fileUploader&&k.fileUploader.queue.length>0}function m(){return k.getFilesAmount()0?T.map(function(e){return e.label}).join(", "):""}function q(){return k.request.loadAttachments().then(function(){o.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function C(){return a.all(T.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){I[e.label]=t})})).catch(function(){I=null})}function P(){return c.valuesOf("safe_file_extension").then(function(e){T=e})}function D(e){return!e.attachment_id||k.canManage}function R(){e.forEach(w,function(e){e()})}function A(e,t){k.fileUploader.queue&&k.fileUploader.queue.length>0?k.fileUploader.uploadAll({entityID:k.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var T=[],w=[],I={},k=Object.create(this);return k.filesLoaded=!1,k.fileUploader=null,k.today=Date.now(),k.userDateFormatWithTime=r.DATE_FORMAT+" HH:mm",k.userDateFormat=r.DATE_FORMAT,k.$onDestroy=R,k.canRemoveAttachment=D,k.canSubmit=d,k.canUploadMore=m,k.formatDateTime=f,k.getAuthorName=p,k.getFilesAmount=h,k.listFileTypes=y,function(){o.$broadcast("LeaveRequestPopup::childComponent::register"),s.$emit("LeaveRequestPopup::addTab",k),g(),a.all([P(),q()]).then(_).finally(function(){k.filesLoaded=!0})}(),k}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,o){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var o,s=this;s.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"},{type:"toil",icon:"calendar-plus-o",label:"Overtime"}],s.openLeavePopup=a,function(){o=n.parse(),o.openModal&&a(null,o.openModal,s.selectedContactId,s.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{btnClass:"@",contactId:"<",selectedContactId:"<",isSelfRecord:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/staff-leave-report.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(t,n,a,o,s,r,i,c,u,l,d,m){function f(e,t){t.data.push(e),t.dataIndex[e.id]=e}function p(e){E(e),W.sections.other.open&&f(e,W.sections.other)}function h(){Object.values(W.sections).forEach(function(e){e.data=[]})}function v(e){var t=U[e.status];t?t(e.leaveRequest):W.refresh()}function b(t){t.dataIndex=e.indexBy(t.data,"id")}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function _(){return s.all().then(function(t){W.absencePeriods=e.sortBy(t,"start_date"),W.selectedPeriod=e.find(W.absencePeriods,function(e){return!0===e.current})})}function y(){return r.all().then(r.loadCalculationUnits).then(function(t){W.absenceTypes=t,W.absenceTypesIndexed=e.indexBy(t,"id")})}function q(){return T("approved",{status_id:F(m.statusNames.approved)})}function C(){return n.all([c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,null,!0),c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,[F(m.statusNames.approved)]),c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,[F(m.statusNames.awaitingApproval),F(m.statusNames.moreInformationRequired)])]).then(function(e){W.absenceTypes.forEach(function(t){t.balanceChanges={holidays:e[0][t.id],approved:e[1][t.id],pending:e[2][t.id]}})})}function P(){return i.all({contact_id:W.contactId,period_id:W.selectedPeriod.id},!0).then(function(e){W.entitlements=e}).then(function(){W.absenceTypesFiltered=W.absenceTypes.filter(function(t){var n=e.find(W.entitlements,function(e){return e.type_id===t.id});return t.entitlement=n?n.value:0,t.remainder=n?n.remainder:{current:0,future:0},!(0===t.entitlement&&"1"!==t.allow_overuse&&"1"!==t.allow_accruals_request)})})}function D(){return i.breakdown({contact_id:W.contactId,period_id:W.selectedPeriod.id},W.entitlements).then(function(){return O(W.entitlements)}).then(function(e){W.sections.entitlements.data=e})}function R(){return n.all([i.breakdown({contact_id:W.contactId,period_id:W.selectedPeriod.id,expired:!0}),A({request_type:"toil",expired:!0})]).then(function(e){return n.all({expiredBalanceChangesFlatten:O(e[0]),expiredTOILS:$(e[1].list)})}).then(function(t){W.sections.expired.data=t.expiredBalanceChangesFlatten.concat(t.expiredTOILS),W.sections.expired.data=e.sortBy(W.sections.expired.data,"expiry_date")})}function A(t){return c.all(e.assign({contact_id:W.contactId,from_date:{from:W.selectedPeriod.start_date},to_date:{to:W.selectedPeriod.end_date},type_id:{IN:W.absenceTypes.map(function(e){return e.id})}},t),null,"from_date ASC",null,!1)}function T(e,t){return A(t).then(function(t){W.sections[e].data=t.list})}function w(){return n.all(Object.values(W.sections).filter(function(e){return e.open}).map(S))}function I(){return T("other",{status_id:{in:[F(m.statusNames.rejected),F(m.statusNames.cancelled)]}})}function k(){return T("pending",{status_id:{ -in:[F(m.statusNames.awaitingApproval),F(m.statusNames.moreInformationRequired)]}})}function L(){return T("holidays",{public_holiday:!0})}function S(e){return e.loading=!0,e.loadLeaveRequests().then(b.bind(this,e)).then(function(){e.loading=!1})}function M(){return u.valuesOf("hrleaveandabsences_leave_request_status").then(function(t){W.leaveRequestStatuses=e.indexBy(t,"value")})}function O(t){return n.resolve().then(function(){return t.map(function(t){var n=e.find(W.entitlements,function(e){return e.id===t.id});return t.breakdown.map(function(t){return e.assign(e.clone(t),{type_id:n.type_id})})})}).then(function(e){return Array.prototype.concat.apply([],e)})}function $(e){return n.resolve().then(function(){return e.map(function(e){return{expiry_date:e.toil_expiry_date,type:{label:"Accrued TOIL"}}})})}function x(){l.subscribe("LeaveRequest::new",function(){W.refresh()}),l.subscribe("LeaveRequest::edit",function(){W.refresh()}),l.subscribe("LeaveRequest::statusUpdate",v),l.subscribe("LeaveRequest::delete",function(e){E(e)})}function E(t){e.forEach(W.sections,function(n,a){n.dataIndex[t.id]&&(e.remove(n.data,function(e){return e.id===t.id}),delete n.dataIndex[t.id],B(t,a))})}function B(e,t){var n=W.absenceTypesIndexed[e.type_id],a="pending"===t?"future":"current";n.balanceChanges[t]-=e.balance_change,n.remainder[a]-=e.balance_change}function N(){W.loading.content=!0,n.all([P(),C()]).then(function(){W.loading.content=!1}).then(function(){return n.all([w(),h()])})}function j(e){var t=W.sections[e];t.open=!t.open,t.open&&!t.data.length&&S(t)}function F(t){return e.find(W.leaveRequestStatuses,function(e){return e.name===t}).value}t.debug("Component: staff-leave-report");var U={delete:E,cancel:p},W=this;W.absencePeriods=[],W.absenceTypes=[],W.absenceTypesFiltered=[],W.absenceTypesIndexed={},W.dateFormat=d.DATE_FORMAT,W.leaveRequestStatuses={},W.selectedPeriod=null,W.role="absence-tab"===a.section?"admin":"staff",W.loading={content:!0,page:!0},W.sections={approved:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:q},entitlements:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:D},expired:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:R},holidays:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:L},pending:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:k},other:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:I}},W.labelPeriod=g,W.refresh=N,W.toggleSection=j,function(){n.all([M(),y(),_()]).then(function(){W.loading.page=!1}).then(function(){return n.all([P(),C()])}).then(function(){W.loading.content=!1}),x()}()}n.component("staffLeaveReport",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/staff-leave-report.html"}],controllerAs:"report",controller:["$log","$q","$rootScope","checkPermissions","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","OptionGroup","pubSub","HR_settings","shared-settings",a]})}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["leave-absences/shared/modules/controllers"],function(e){function t(e,t,n,a){function o(){return a.request.calculateBalanceChange(a.selectedAbsenceType.calculation_unit_name)}function s(){var e=a.request,t=!!e.from_date&&!!e.to_date,n=a.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function r(){return a.canCalculateChange()}function i(){return n.resolve()}t.debug("RequestModalDetailsLeaveController"),a.calculateBalanceChange=o,a.canCalculateChange=s,a.canSubmit=r,a.initChildController=i}e.controller("RequestModalDetailsLeaveController",t),t.$inject=["$controller","$log","$q","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,o,s){function r(){return!(!s.canCalculateChange()||!s.request.sickness_reason)}function i(){return a.all([l(),d()])}function c(t){var n=s.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function u(t){return!!e.find(s.sicknessDocumentTypes,function(e){return e.value===t})}function l(){return o.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){s.sicknessDocumentTypes=e})}function d(){return o.valuesOf("hrleaveandabsences_sickness_reason").then(function(t){s.sicknessReasons=e.indexBy(t,"name")})}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:s}),s.canSubmit=r,s.initChildController=i,s.isChecked=c,s.isDocumentInRequest=u}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,o,s,r){function i(){return r.balance.change.amount=+r.request.toil_to_accrue,n.resolve(r.balance.change)}function c(){return f().catch(function(e){return e.length&&(r.errors=e),n.reject(e)}).then(function(e){return s.calculateToilExpiryDate(r.request.type_id,e)}).then(function(e){return r.request.toil_expiry_date=e,r.uiOptions.expiryDate=new Date(e),e})}function u(){return!!r.request.toil_to_accrue}function l(){var e=r.uiOptions.multipleDays&&!!r.request.to_date,t=!r.uiOptions.multipleDays&&!!r.request.from_date,n=t||e,a=D.from_date!==r.request.from_date||D.to_date!==r.request.to_date;return r.canDisplayToilExpirationField&&n&&R.hasExpirationFromAdminSettings&&a}function d(){return!!(r.request.from_date&&r.request.to_date&&r.request.toil_duration&&r.request.toil_to_accrue)}function m(){r.request.toil_expiry_date=!1,r.uiOptions.expiryDate=null}function f(){var e=r.uiOptions.multipleDays,t=r.request;return p({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function p(e){if(e.hasErrors){var t="Please select "+e.label+" to find expiry date";return n.reject([t])}return e.value?n.resolve(e.value):n.reject([])}function h(){var e=r.isMode("create")&&R.hasExpirationFromAdminSettings,t=R.hasPreviousExpirationDate,n=r.isLeaveType("toil"),a=r.canManage;r.canDisplayToilExpirationField=n&&(a||e||t)}function v(){return R.hasPreviousExpirationDate=r.isMode("edit")&&!!r.request.toil_expiry_date,s.canExpire(r.request.type_id).then(function(e){R.hasExpirationFromAdminSettings=e})}function b(){return r.request.to_date_type=r.request.from_date_type="1",v().then(h).then(g).then(y)}function g(){r.canManage&&(r.uiOptions.expiryDate=r.convertDateFormatFromServer(r.request.toil_expiry_date))}function _(){r.isMode("view")||a.$watch(function(){return r.request.toil_to_accrue},function(e,t){+e!=+t&&r.performBalanceChangeCalculation()})}function y(){return o.valuesOf("hrleaveandabsences_toil_amounts").then(function(t){r.toilAmounts=e.indexBy(t,"value")})}function q(){D=angular.copy(r.request.attributes())}function C(){return l()?c().catch(n.resolve):n.resolve()}function P(){r.uiOptions.expiryDate&&(r.request.toil_expiry_date=r.convertDateToServerFormat(r.uiOptions.expiryDate))}t.debug("RequestModalDetailsToilController");var D,R={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};r.canDisplayToilExpirationField=!1,r.calculateBalanceChange=i,r.canCalculateChange=u,r.canSubmit=d,r.clearExpiryDate=m,r.initChildController=b,r.onDateChangeExtended=C,r.setDaysSelectionModeExtended=C,r.updateExpiryDate=P,function(){_(),q()}()}t.controller("RequestModalDetailsToilController",n),n.$inject=["$log","$q","$rootScope","api.optionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/absence-period.instance",["leave-absences/shared/modules/models-instances","common/moment","common/models/instances/instance","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriodInstance",["$log","ModelInstance","HR_settings",function(e,n,a){return e.debug("AbsencePeriodInstance"),n.extend({defaultCustomData:function(){return{current:!1}},transformAttributes:function(e){var n=t();return e.current=!1,t(e.start_date).isSameOrBefore(n,"day")&&t(e.end_date).isSameOrAfter(n,"day")&&(e.current=!0),e},isInPeriod:function(e){var n=a.DATE_FORMAT.toUpperCase(),o=t(e,n);return t(this.start_date).isSameOrBefore(o)&&t(this.end_date).isSameOrAfter(o)}})}])}),define("leave-absences/shared/apis/absence-period.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("AbsencePeriodAPI",["$log","api",function(e,t){return e.debug("AbsencePeriodAPI"),t.extend({all:function(t){return e.debug("AbsencePeriodAPI"),this.sendGET("AbsencePeriod","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/models/absence-period.model",["leave-absences/shared/modules/models","common/moment","leave-absences/shared/modules/shared-settings","leave-absences/shared/instances/absence-period.instance","leave-absences/shared/apis/absence-period.api","common/models/model","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriod",["$log","Model","AbsencePeriodAPI","AbsencePeriodInstance","shared-settings",function(e,n,a,o,s){return e.debug("AbsencePeriod"),n.extend({all:function(e){return a.all(e).then(function(e){return e.map(function(e){return o.init(e,!0)})})},current:function(){var e=t().format(s.serverDateFormat),n={start_date:{"<=":e},end_date:{">=":e}};return a.all(n).then(function(e){return e&&e.length?o.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,o,s){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return o.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var o=e(n).format(s.serverDateFormat),r={date:o};return a.all(r).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={toilDurationHours:"0",toilDurationMinutes:"0",request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},transformAttributes:function(e){var t=Number(e.toil_duration);return t&&(e.toilDurationHours=Math.floor(t/60).toString(),e.toilDurationMinutes=(t%60).toString()),e},updateDuration:function(){this.toil_duration=60*Number(this.toilDurationHours)+Number(this.toilDurationMinutes)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files","toilDurationHours","toilDurationMinutes"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function o(t,o,s,r,i,c,u,l,d,m,f,p,h,v,b,g,_,y,q,C,P){function D(e){"days"===$e.selectedAbsenceType.calculation_unit_name?delete $e.request[e+"_date_amount"]:delete $e.request[e+"_date_type"]}function R(){["from","to"].forEach(D)}function A(){var e=$e.requestStatuses[y.statusNames.awaitingApproval].value;Ie.status_id===e&&e!==$e.request.status_id&&d.publish("ManagerBadge:: Update Count")}function T(){return Oe.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function w(){return Oe.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function I(){return!$e.loading.entitlements&&(!!se("admin")||!ae("view")&&!(se("manager")&&!ae("create")))}function k(){var e=T();return $e.isMode("edit")&&(e=e&&(G()||w())),$e.canManage&&$e.requestStatuses&&(e=e&&!!$e.getStatusFromValue($e.newStatusOnSave)),(e=e&&!!$e.period.id)&&!$e.isMode("view")}function L(){$e.isSelfRecord?$e.request.status_id=$e.requestStatuses[y.statusNames.awaitingApproval].value:$e.canManage&&($e.request.status_id=$e.newStatusOnSave||$e.request.status_id)}function S(){if($e.isMode("edit")&&!$e.isRole("staff")&&"toil"!==F())return $e.request.calculateBalanceChange($e.selectedAbsenceType.calculation_unit_name).then(function(e){if(+$e.balance.change.amount!=+e.amount)return P.promptBalanceChangeRecalculation().then(function(){s.$emit("LeaveRequestPopup::recalculateBalanceChange")}),o.reject()})}function M(){$e.errors=[]}function O(){return $e.request.create().then(Ce).then(function(){fe("LeaveRequest::new")})}function $(){ee()&&!$e.isRole("staff")&&($e.request.change_balance=!0)}function x(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return $e.request.delete().then(function(){$e.dismissModal(),d.publish("LeaveRequest::delete",$e.request)})}})}function E(){i.dismiss({$value:"cancel"})}function B(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function N(){return j($e.getStatusFromValue($e.request.status_id).name)}function j(e){return n.map(Te[e],function(e){return $e.requestStatuses[e]})}function F(){return $e.request?$e.request.request_type:$e.leaveType||null}function U(){return!$e.request||e.equals({},$e.requestStatuses)?[]:$e.request.status_id?N():j("none")}function W(e){return n.find($e.requestStatuses,function(t){return t.value===e})}function H(e){$e.errors=n.isArray(e)?e:[e],$e.loading.absenceTypes=!1,$e.submitting=!1}function G(){return!e.equals(Ie,$e.request.attributes())||$e.canManage&&$e.newStatusOnSave}function Y(){return $e.postContactSelection=!0,$e.staffMemberSelectionComplete=!1,$e.request.contact_id?o.resolve().then(ie).then(ce).then(he).then(be).then(Z).then(z).then($e.isMode("edit")?ge:n.noop).then(function(){$e.postContactSelection=!1,$e.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Se)return o.reject(e)}):o.reject("The contact id was not set")}function V(){var e=[y.statusNames.moreInformationRequired,y.statusNames.approved,y.statusNames.rejected,y.statusNames.cancelled];Te.none=[y.statusNames.moreInformationRequired,y.statusNames.approved],Te.awaiting_approval=e,Te.more_information_required=e,Te.rejected=e,Te.approved=e,Te.cancelled=[y.statusNames.awaitingApproval].concat(e)}function z(){return $e.canManage?f.find($e.request.contact_id).then(function(e){$e.contactName=e.display_name}):o.resolve()}function X(){ke.push(s.$on("LeaveRequestPopup::requestObjectUpdated",ge),s.$on("LeaveRequestPopup::absencePeriodChanged",function(){ce().then(he).then(function(){s.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",$e.absenceTypes)})}),s.$on("LeaveRequestPopup::handleError",function(e,t){H(t)}),s.$on("LeaveRequestPopup::childComponent::register",function(){we++})),r.$on("$destroy",Pe),r.$on("LeaveRequestPopup::addTab",function(e,t){Oe.push(t)})}function Q(){var e,t;$e.request=$e.leaveRequest||null,e=F(),t=$e.initRequestAttributes(),"leave"===e?$e.request=_.init(t):"sickness"===e?$e.request=q.init(t):"toil"===e&&($e.request=C.init(t))}function J(){var e={};return $e.request?e=$e.request.attributes():$e.canManage||(e={contact_id:Le}),e}function K(){if(Me="staff","my-leave"!==s.section)return c(y.permissions.admin.administer).then(function(e){e&&(Me="admin")}).then(function(){return"staff"===Me&&c(y.permissions.ssp.manage).then(function(e){e&&(Me="manager")})}).finally(function(){$e.canManage=$e.isRole("manager")||$e.isRole("admin")})}function Z(){($e.isRole("admin")||$e.isMode("create")&&$e.isRole("manager"))&&($e.newStatusOnSave=$e.requestStatuses[y.statusNames.approved].value)}function ee(){return!$e.request.status_id||!n.includes(["cancelled","rejected"],W($e.request.status_id).name)}function te(e){var t=$e.getStatusFromValue($e.request.status_id);return!!t&&t.name===e}function ne(e){return $e.request&&$e.request.request_type===e}function ae(e){return $e.mode===e}function oe(e,t){var n=a(e.from_date),o=a(e.to_date);return n.isSameOrAfter(t.start_date)&&o.isSameOrBefore(t.end_date)}function se(e){return Me===e}function re(){return h.all().then(function(e){$e.absencePeriods=e})}function ie(){return v.all(B()).then(v.loadCalculationUnits).then(function(e){Ae={types:e,ids:e.map(function(e){return e.id})}})}function ce(){return $e.loading.entitlements=!0,b.all({contact_id:$e.request.contact_id,period_id:$e.period.id,type_id:{IN:Ae.ids}},!0).finally(function(){$e.loading.entitlements=!1})}function ue(){return p.get().then(function(e){Le=e.contactId})}function le(){return $e.selectedContactId?f.find($e.selectedContactId).then(function(e){$e.managedContacts=[e]}):$e.isRole("admin")?f.all().then(function(e){$e.managedContacts=n.remove(e.list,function(e){return e.id!==Le})}):f.find(Le).then(function(e){return e.leaveManagees()}).then(function(e){$e.managedContacts=e})}function de(){return u.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){$e.requestStatuses=n.indexBy(e,"name")})}function me(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function fe(e){A(),d.publish(e,$e.request),$e.errors=[],$e.dismissModal()}function pe(){["from","to"].forEach(function(e){$e.request[e+"_date"]=Ie[e+"_date"]})}function he(e){if($e.absenceTypes=me(Ae.types,e),!$e.absenceTypes.length)return o.reject(Se)}function ve(){$e.period=n.find($e.absencePeriods,function(e){return $e.isMode("create")?e.current:oe($e.request,e)})}function be(){$e.isMode("create")?($e.selectedAbsenceType=$e.absenceTypes[0],$e.request.type_id=$e.selectedAbsenceType.id):$e.selectedAbsenceType=n.find($e.absenceTypes,function(e){return e.id===$e.request.type_id})}function ge(){Ie=e.copy($e.request.attributes())}function _e(){var e;$e.request.id?(e=[$e.requestStatuses[y.statusNames.approved].value,$e.requestStatuses[y.statusNames.adminApproved].value,$e.requestStatuses[y.statusNames.rejected].value,$e.requestStatuses[y.statusNames.cancelled].value],$e.mode="edit",$e.isRole("staff")&&e.indexOf($e.request.status_id)>-1&&($e.mode="view")):$e.mode="create"}function ye(){var e=$e.request.status_id;if(!$e.isMode("view")&&!$e.submitting)return $e.submitting=!0,L(),R(),$e.request.isValid().then(ee()&&S).then($).then(!$e.request.change_balance&&pe).then(qe).then(function(){return $e.isMode("edit")?Re():O()}).catch(function(t){$e.request.status_id=e,t&&H(t)}).finally(function(){$e.submitting=!1})}function qe(){return o.all(Oe.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function Ce(){function e(e){e&&n.push(e),++a===we&&(n.length>0?t.reject(n):t.resolve())}var t=o.defer(),n=[],a=0;return we>0?s.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function Pe(){ke.forEach(function(e){e()})}function De(){s.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function Re(){return $e.request.update().then(Ce).then(function(){$e.isRole("manager")?fe("LeaveRequest::updatedByManager"):($e.isRole("staff")||$e.isRole("admin"))&&fe("LeaveRequest::edit")})}t.debug("RequestCtrl");var Ae,Te={},we=0,Ie={},ke=[],Le="",Se="No entitlement",Me="",Oe=[],$e=n.assign(this,m);$e.absencePeriods=[],$e.absenceTypes=[],$e.canManage=!1,$e.contactName=null,$e.errors=[],$e.loading={absenceTypes:!0,entitlements:!0},$e.managedContacts=[],$e.mode="",$e.newStatusOnSave=null,$e.period={},$e.postContactSelection=!1,$e.requestStatuses={},$e.selectedAbsenceType={},$e.staffMemberSelectionComplete=!1,$e.submitting=!1,$e.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},$e.canChangeAbsenceType=I,$e.canSubmit=k,$e.closeAlert=M,$e.deleteLeaveRequest=x,$e.dismissModal=E,$e.getStatuses=U,$e.getStatusFromValue=W,$e.initAfterContactSelection=Y,$e.initRequestAttributes=J,$e.isLeaveStatus=te,$e.isLeaveType=ne,$e.isMode=ae,$e.isRole=se,$e.submit=ye,$e.updateAbsenceType=De,function(){$e.loading.absenceTypes=!0,V(),X(),o.all([ue(),K(),re(),de()]).then(Q).then(_e).then(ve).then(function(){return $e.canManage&&!$e.isMode("edit")&&le()}).then(function(){if($e.selectedContactId&&($e.request.contact_id=$e.selectedContactId),$e.request.contact_id)return $e.initAfterContactSelection()}).catch(H).finally(function(){$e.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",o),o.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,o,s,r,i,c){function u(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,o,r,i){a.open({appendTo:t.children().eq(0),templateUrl:s.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:o,isSelfRecord:r,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return c.find(e).then(function(e){return u(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):o.error("Error","You dont have permission to see this leave request")})}).catch(function(e){o.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/absence-tab/modules/components",["common/angular"],function(e){return e.module("absence-tab.components",[])}),function(e){define("leave-absences/absence-tab/components/absence-tab-container.component",["leave-absences/absence-tab/modules/components"],function(t){function n(t,n,a){t.debug("Component: absence-tab-container"),n.section="absence-tab",this.contactId=e.adminId,function(){a.getDateFormat()}()}t.component("absenceTabContainer",{templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-container.html"}],controllerAs:"absence",controller:n}),n.$inject=["$log","$rootScope","DateFormat"]})}(CRM),define("leave-absences/absence-tab/components/absence-tab-entitlements.component",["common/lodash","leave-absences/absence-tab/modules/components"],function(e,t){function n(e,t,n){function a(){return n.all().then(n.loadCalculationUnits).then(function(e){o.absenceTypes=e})}t.debug("Component: absence-tab-entitlements");var o=this;o.absenceTypes=[],o.loading={component:!0},function(){a().finally(function(){o.loading.component=!1})}()}t.component("absenceTabEntitlements",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-entitlements.html"}],controllerAs:"entitlements",controller:n}),n.$inject=["$q","$log","AbsenceType"]}),define("leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component",["common/moment","leave-absences/absence-tab/modules/components"],function(e,t){function n(t,n,a,o,s,r){function i(e){l.errorMessage=e}function c(){return r.get({is_active:!0}).then(function(e){l.workPatterns=e})}function u(){return o.valuesOf("hrjc_revision_change_reason").then(function(e){l.changeReasons=e})}t.debug("Component: absence-tab-custom-work-pattern-modal");var l=Object.create(this);return l.changeReasons=[],l.errorMessage="",l.saveInProgress=!1,l.workPatterns=[],l.loading={content:!0},l.selected={workPattern:null,effectiveDate:null,changeReason:null},l.uiOptions={effectiveDate:{show:!1,options:{startingDay:1,showWeeks:!1}}},function(){n.all([c(),u()]).finally(function(){l.loading.content=!1})}(),l.closeModal=function(){l.dismiss({$value:"cancel"})},l.closeAlert=function(){l.errorMessage=""},l.save=function(){var t=e(l.selected.effectiveDate).format(s.serverDateFormat);return l.saveInProgress=!0,r.assignWorkPattern(l.contactId,l.selected.workPattern.id,t,null,l.selected.changeReason).then(function(){a.$broadcast("CustomWorkPattern::Added"),l.closeModal()}).catch(i).finally(function(){l.saveInProgress=!1})},l}t.component("absenceTabCustomWorkPatternModal",{bindings:{contactId:"<",dismiss:"&"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-custom-work-pattern-modal.html"}],controllerAs:"workPatternModal",controller:["$log","$q","$rootScope","OptionGroup","shared-settings","WorkPatternAPI",n]})}),define("leave-absences/absence-tab/components/absence-tab-work-patterns.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component"],function(e,t,n){function a(n,a,o,s,r,i,c,u,l,d){function m(){return d.workPatternsOf(g.contactId,{},!1).then(function(e){g.customWorkPatterns=e})}function f(){return d.default().then(function(e){g.defaultWorkPattern=e})}function p(){return l.valuesOf("hrjc_revision_change_reason").then(function(t){b=e.indexBy(t,"value")})}function h(e){var t=[m()];return e&&(t=t.concat(e)),g.loading.workPattern=!0,a.all(t).then(function(){v()}).finally(function(){g.loading.workPattern=!1})}function v(){var n,a=u.DATE_FORMAT.toUpperCase();g.customWorkPatterns=e(g.customWorkPatterns).map(function(e){return n=b[e.change_reason],e.change_reason_label=n?n.label:"",e.effective_date=e.effective_date?t(e.effective_date).format(a):"",e}).sortBy(function(e){return-t(e.effective_date,a).valueOf()}).value()}n.debug("Component: absence-tab-work-patterns");var b=[],g=Object.create(this);return g.customWorkPatterns=[],g.defaultWorkPattern=null,g.linkToWorkPatternListingPage=function(){var e=CRM.url("civicrm/contact/view",{cid:g.contactId,selectedChild:"absence"});return CRM.url("civicrm/admin/leaveandabsences/work_patterns",{cid:g.contactId,returnUrl:e})}(),g.loading={workPattern:!0},function(){h([p(),f(),c.getDateFormat()]),s.$on("CustomWorkPattern::Added",function(){h()})}(),g.deleteWorkPattern=function(e){i.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){d.unassignWorkPattern(e).then(function(){h()})}})},g.openModal=function(){r.open({appendTo:o.children().eq(0),template:'',controller:["$uibModalInstance",function(e){this.dismiss=e.dismiss}],controllerAs:"$ctrl"})},g}n.component("absenceTabWorkPatterns",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-work-patterns.html"}],controllerAs:"workpatterns",controller:["$log","$q","$rootElement","$rootScope","$uibModal","dialog","DateFormat","HR_settings","OptionGroup","WorkPattern",a]})}),define("leave-absences/absence-tab/components/annual-entitlement-change-log.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contract"],function(e,t,n){function a(n,a,o,s,r){function i(){return l().then(function(e){q=q.concat(e)})}function c(){var t=e.groupBy(q,"created_date");C.changeLogRows=e.map(t,d).sort(function(e,t){return t.date.diff(e.date)})}function u(e,t){var n,a,o=m(e);e.entitlements.forEach(function(s,r){n=o.entitlements.slice(0,r),a=e.entitlements.slice(r+1),t(s,n,a)})}function l(){return o.all({contact_id:C.contactId,period_id:C.periodId},!1).then(function(e){return e.map(function(e){return{comment:e.comment,contact_id:e.contact_id,created_date:e.created_date,editor_id:e.editor_id,entitlement_amount:e.value,entitlement_id:e.id,"entitlement_id.type_id":e.type_id}})})}function d(n,a){var o,s,r;return s=e.indexBy(n,"entitlement_id.type_id"),r=C.absenceTypes.map(function(t){return o=s[t.id],e.extend({calculation_unit:t.calculation_unit_name},o)}),{date:t(a),entitlements:r}}function m(e){var t;return t=C.changeLogRows.indexOf(e),C.changeLogRows[t+1]||{date:e.date.clone(),entitlements:e.entitlements.map(function(){return{}})}}function f(){for(var t,n,a,o=C.changeLogRows.length-1;o>=0;o--)if(t=C.changeLogRows[o],n=e.pluck(t.entitlements,"comment"),a=e.compact(n),1===a.length){var s=e.findIndex(n,"length");t.highlightedEntitlement=t.entitlements[s]}else a.length>1&&_(o)}function p(e,t){C.changeLogRows.splice(t,0,e)}function h(){return n.all({id:C.periodId}).then(function(e){C.absencePeriod=e[0]})}function v(e){return a.all().then(a.loadCalculationUnits).then(function(e){C.absenceTypes=e})}function b(){return o.logs({contact_id:C.contactId,period_id:C.periodId}).then(function(e){q=e})}function g(){var e,t;if(!(C.changeLogRows.length<=1))for(e=C.changeLogRows.length-2,t=C.changeLogRows.length-1;e>=0;){ -var n=C.changeLogRows[e],a=C.changeLogRows[t];n.entitlements.forEach(function(e,t){var n=a.entitlements[t];e.comment===n.comment&&delete e.comment}),e--,t--}}function _(e){var t,n,a=C.changeLogRows[e];u(a,function(o,s,r){o.comment&&(t=s.concat(o).concat(r),n={date:a.date.clone(),entitlements:t},n.highlightedEntitlement=o,p(n,e++))}),y(e)}function y(e){C.changeLogRows.splice(e,1)}var q=[],C=this;C.absencePeriod=null,C.absenceTypes=[],C.changeLogRows=[],C.loading={component:!0},function(){h().then(v).then(b).then(i).then(c).then(g).then(f).finally(function(){C.loading.component=!1})}()}n.component("annualEntitlementChangeLog",{bindings:{contactId:"<",periodId:"<",dismissModal:"&"},templateUrl:["settings",function(e){return e.pathTpl+"components/annual-entitlement-change-log.html"}],controllerAs:"changeLog",controller:a}),a.$inject=["AbsencePeriod","AbsenceType","Entitlement","OptionGroup","shared-settings"]}),function(e){define("leave-absences/absence-tab/components/annual-entitlements.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contact"],function(t,n,a){function o(a,o,s,r,i,c,u,l,d){function m(){P.absencePeriods=t.chain(P.absencePeriods).filter(function(e){return t.find(q,function(t){return t.period_id===e.id})}).sortBy(function(e){return-n(e.start_date).valueOf()}).value()}function f(){P.absenceTypes=t.filter(P.absenceTypes,function(e){return t.find(q,function(t){return t.type_id===e.id})})}function p(t){var n=e.url("civicrm/contact/view",{cid:P.contactId,selectedChild:"absence"});return e.url("civicrm/admin/leaveandabsences/periods/manage_entitlements",{id:t,cid:P.contactId,returnUrl:n})}function h(){return c.all().then(function(e){P.absencePeriods=e})}function v(){var e=t.uniq(t.map(q,function(e){return e.editor_id}));return l.all({id:{IN:e}}).then(function(e){C=t.indexBy(e.list,"contact_id")})}function b(){return u.all({contact_id:P.contactId}).then(function(e){q=e})}function g(e){r.open({appendTo:s.children().eq(0),templateUrl:"annual-entitlement-change-log-modal",controller:["$uibModalInstance",function(t){this.contactId=P.contactId,this.dismiss=t.dismiss,this.periodId=e}],controllerAs:"modal"})}function _(){P.absencePeriods=t.map(P.absencePeriods,function(e){var n=t.map(P.absenceTypes,function(n){var a=t.find(q,function(t){return t.type_id===n.id&&t.period_id===e.id});return a?{amount:a.value,calculation_unit:n.calculation_unit_name,comment:a.comment?{message:a.comment,author_name:C[a.editor_id].display_name,date:a.created_date}:null}:null});return{id:e.id,title:e.title,entitlements:n}})}function y(e){var t=e.message+"

    Last updated:
    By: "+e.author_name+"
    Date: "+n.utc(e.date).local().format("DD/M/YYYY HH:mm")+"
    ";d.info("Calculation comment:",t)}a.debug("Component: annual-entitlements");var q=[],C=[],P=this;P.absencePeriods=[],P.loading={absencePeriods:!0},P.getEditEntitlementsPageURL=p,P.openAnnualEntitlementChangeLog=g,P.showComment=y,function(){b().then(v).then(h).then(m).then(f).then(_).finally(function(){P.loading.absencePeriods=!1})}()}a.component("annualEntitlements",{bindings:{absenceTypes:"<",contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/annual-entitlements.html"}],controllerAs:"entitlements",controller:o}),o.$inject=["$log","$q","$rootElement","$uibModal","AbsenceType","AbsencePeriod","Entitlement","Contact","notificationService"]})}(CRM),define("leave-absences/absence-tab/components/contract-entitlements.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contract"],function(e,t,n){function a(n,a,o,s,r,i){function c(){m.absenceTypes=e.filter(m.absenceTypes,function(t){return e.find(m.contracts,function(n){return e.find(n.info.leave,function(e){return e.leave_type===t.id})})})}function u(e){var n=o.DATE_FORMAT.toUpperCase();return e?t(e).format(n):""}function l(){return r.all({contact_id:m.contactId}).then(function(e){m.contracts=e})}function d(){m.contracts=e.sortBy(m.contracts,function(e){return t(e.info.details.period_start_date)}).map(function(t){var n=t.info,a=n.details,o=e.map(m.absenceTypes,function(t){var a=e.filter(n.leave,function(e){return e.leave_type===t.id})[0];return{amount:a?a.leave_amount:"",calculation_unit:t.calculation_unit_name}});return{position:a.position,start_date:u(a.period_start_date),end_date:u(a.period_end_date),absences:o}})}n.debug("Component: contract-entitlements");var m=this;m.contracts=[],m.loading={contracts:!0},function(){i.getDateFormat().then(l).then(c).then(d).finally(function(){m.loading.contracts=!1})}()}n.component("contractEntitlements",{bindings:{absenceTypes:"<",contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/contract-entitlements.html"}],controllerAs:"entitlements",controller:a}),a.$inject=["$log","$q","HR_settings","AbsenceType","Contract","DateFormat"]}),function(e){define("leave-absences/absence-tab/modules/settings",["common/angular"],function(t){return t.module("absence-tab.settings",[]).constant("settings",{contactId:e.vars.leaveAndAbsences.contactId,debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/absence-tab/"})})}(CRM),define("leave-absences/absence-tab/modules/config",["common/angular","leave-absences/absence-tab/modules/settings"],function(e){return e.module("absence-tab.config",["absence-tab.settings"]).config(["$resourceProvider","$httpProvider","$logProvider","settings",function(e,t,n,a){n.debugEnabled(a.debug),e.defaults.stripTrailingSlashes=!1,t.defaults.headers.common["X-Requested-With"]="XMLHttpRequest"}])}),define("leave-absences/absence-tab/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/modules/directives","common/services/check-permissions","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/modules/shared-settings","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/work-pattern.model","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/staff-leave-report.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/work-pattern.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/absence-tab/components/absence-tab-container.component","leave-absences/absence-tab/components/absence-tab-entitlements.component","leave-absences/absence-tab/components/absence-tab-work-patterns.component","leave-absences/absence-tab/components/annual-entitlement-change-log.component","leave-absences/absence-tab/components/annual-entitlements.component","leave-absences/absence-tab/components/contract-entitlements.component","leave-absences/absence-tab/modules/config"],function(e){return e.module("absence-tab",["ngResource","ui.bootstrap","textAngular","common.angularDate","common.dialog","common.directives","common.filters","common.services","common.mocks","leave-absences.settings","leave-absences.models","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","leave-absences.settings","absence-tab.config","absence-tab.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/absence-tab":n+"/absence-tab"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/absence-tab/app"],function(){document.dispatchEvent("function"==typeof window.CustomEvent?new CustomEvent("absenceTabReady"):function(){var e=document.createEvent("Event");return e.initEvent("absenceTabReady",!0,!0),e}())})})}(CRM,require),define("absence-tab",function(){}); +!function(e){define("leave-absences/shared/config",[],function(){var n=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":n+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/modules/shared-settings",["common/angular"],function(n){return n.module("leave-absences.settings",[]).constant("shared-settings",{attachmentToken:e.vars.leaveAndAbsences.attachmentToken,debug:e.debug,managerPathTpl:e.vars.leaveAndAbsences.baseURL+"/views/manager-leave/",sharedPathTpl:e.vars.leaveAndAbsences.baseURL+"/views/shared/",serverDateFormat:"YYYY-MM-DD",serverDateTimeFormat:"YYYY-MM-DD HH:mm:ss",permissions:{admin:{access:"access leave and absences",administer:"administer leave and absences"},ssp:{access:"access leave and absences in ssp",manage:"manage leave and absences in ssp"}},fileUploader:{queueLimit:10},statusNames:{approved:"approved",adminApproved:"admin_approved",awaitingApproval:"awaiting_approval",moreInformationRequired:"more_information_required",rejected:"rejected",cancelled:"cancelled"}})})}(CRM),define("leave-absences/shared/modules/apis",["common/angular","common/modules/apis","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.apis",["common.apis","leave-absences.settings"])}),define("leave-absences/shared/modules/models-instances",["common/angular","common/models/instances/instance","common/modules/services","common/modules/models","common/services/check-permissions","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.models.instances",["common.models","common.models.instances","common.services","leave-absences.settings"])}),define("leave-absences/shared/modules/models",["common/angular","common/modules/models","common/modules/services","leave-absences/shared/modules/apis","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){"use strict";return e.module("leave-absences.models",["common.models","common.services","leave-absences.apis","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,n,t){"use strict";t.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(t,a,o){return t.debug("AbsenceTypeAPI"),a.extend({all:function(n){return t.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(n||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,s,i){return t.debug("AbsenceTypeAPI.calculateToilExpiryDate"),i=e.assign({},i,{absence_type_id:a,date:n(s).format(o.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",i).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,n){return e.debug("AbsenceTypeInstance"),n.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,n){"use strict";n.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(n,t,a,o,s,i){return n.debug("AbsenceType"),a.extend({all:function(e){return s.all(e).then(function(e){return e.map(function(e){return i.init(e,!0)})})},calculateToilExpiryDate:function(e,n,t){return s.calculateToilExpiryDate(e,n,t)},canExpire:function(e){return s.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(n){return o.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(t){return t=e.indexBy(t,"value"),e.map(n,function(n){return e.assign(n,{calculation_unit_label:t[n.calculation_unit].label,calculation_unit_name:t[n.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,n){"use strict";n.factory("WorkPatternAPI",["$log","api",function(n,t){function a(n){var t=e.clone(n);return t.workPattern=t["api.WorkPattern.get"].values[0],delete t["api.WorkPattern.get"],t}return n.debug("WorkPatternAPI"),t.extend({assignWorkPattern:function(n,t,a,o,s,i){return this.sendPOST("ContactWorkPattern","create",e.assign({},i,{contact_id:n,pattern_id:t,effective_date:a,effective_end_date:o,change_reason:s})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(t,a,o,s){return n.debug("WorkPatternAPI.getCalendar",t,a,o,s),this.sendGET("WorkPattern","getcalendar",e.assign({},s,{contact_id:e.isArray(t)?{IN:t}:t,start_date:a,end_date:o}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(n,t,o){return this.sendGET("ContactWorkPattern","get",e.assign({},t,{contact_id:n,"api.WorkPattern.get":{id:"$value.pattern_id"}}),o).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,n,t){"use strict";t.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(t,a,o,s,i){function r(n,t){return u().then(function(a){var o=this.days[c(n).valueOf()];return!!o&&e.find(a,function(e){return e.name===t}).value===o.type}.bind(this))}function c(e){return n(e,s.serverDateFormat).clone()}function u(){return l=l||i.valuesOf("hrleaveandabsences_work_day_type")}var l;return o.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return r.call(this,e,"non_working_day")},isWeekend:function(e){return r.call(this,e,"weekend")},isWorkingDay:function(e){return r.call(this,e,"working_day")},transformAttributes:function(n){var t={};return n.calendar.forEach(function(e){t[c(e.date).valueOf()]=e}),e(n).omit("calendar").assign({days:t}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,n){"use strict";n.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(n,t,a,o){return n.debug("Calendar"),t.extend({get:function(t,s,i,r){return n.debug("Calendar.get"),a.getCalendar(t,s,i,r).then(function(n){var a=n.values.map(function(e){return o.init(e)});return e.isArray(t)?a:a[0]})}})}])}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,n){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,t){function a(e){var t=n.clone(e),a=t["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(t.remainder=a[0].remainder),delete t["api.LeavePeriodEntitlement.getremainder"],t}function o(e){var t=n.clone(e),a=t["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return t.value=a,delete t["api.LeavePeriodEntitlement.getentitlement"],t}return e.debug("EntitlementAPI"),t.extend({all:function(n,t){return e.debug("EntitlementAPI.all"),n["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},t&&(n["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",n,!1).then(function(e){return e.values}).then(function(e){return e=e.map(o),t&&(e=e.map(a)),e})},breakdown:function(n){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",n).then(function(e){return e.values})},getLeaveBalances:function(n,t,a,o,s){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",n,t,a,o,"getLeaveBalances",s)}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,n){return e.debug("EntitlementLogAPI"),n.extend({all:function(n){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",n,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,n,t){return e.debug("EntitlementInstance"),n.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return t.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,n){"use strict";n.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(n,t,a,o,s){return n.debug("Entitlement"),t.extend({all:function(e,n){return a.all(this.processFilters(e),n).then(function(e){return e.map(function(e){return o.init(e,!0)})})},breakdown:function(n,t){return a.breakdown(n).then(function(n){return t?(t.map(function(t){var a=e.find(n,function(e){return e.id===t.id});return a&&(t.breakdown=a.breakdown),t}),t):n.map(function(e){return o.init(e,!0)})})},logs:function(n){return n=e.cloneDeep(n||{}),n.contact_id&&(n["entitlement_id.contact_id"]=n.contact_id,delete n.contact_id),n.period_id&&(n["entitlement_id.period_id"]=n.period_id,delete n.period_id),n.return=n.return||[],n.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),s.all(n)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,n){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,t,a){return e.debug("LeaveRequestAPI"),t.extend({all:function(n,t,o,s,i){e.debug("LeaveRequestAPI.all");var r=a.defer();return n&&n.contact_id&&n.contact_id.IN&&0===n.contact_id.IN.length?r.resolve({list:[],total:0,allIds:[]}):r.resolve(this.getAll("LeaveRequest",n,t,o,s,"getFull",i)),r.promise},balanceChangeByAbsenceType:function(n,t,o,s){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var i=a.defer();n&&t||i.reject("contact_id and period_id are mandatory");var r={contact_id:n,period_id:t,statuses:o?{IN:o}:null,public_holiday:s||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",r,!1).then(function(e){i.resolve(e.values)}),i.promise},calculateBalanceChange:function(t){return e.debug("LeaveRequestAPI.calculateBalanceChange",t),this.sendPOST("LeaveRequest","calculatebalancechange",t).then(function(e){return e.values.breakdown=n.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,n){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:n.toString()},!1)},create:function(n){return e.debug("LeaveRequestAPI.create",n),this.sendPOST("LeaveRequest","create",n).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,t,a){return a=n.assign({},a,{leave_request_id:e,attachment_id:t}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,t){return t=n.assign({},t,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",t).then(function(e){return e.values})},find:function(n){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:n}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,t){return t=n.assign({},t,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",t,!1).then(function(e){return e.values})},getComments:function(e,t){return t=n.assign({},t,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",t,!1).then(function(e){return e.values})},isManagedBy:function(n,t){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:n,contact_id:t}).then(function(e){return e.values})},isValid:function(t){e.debug("LeaveRequestAPI.isValid",t);var o=a.defer();return this.sendPOST("LeaveRequest","isValid",t).then(function(e){e.count>0?o.reject(n(e.values).map().flatten().value()):o.resolve(e.values)}),o.promise},saveComment:function(e,t,a){return a=n.assign({},a,{leave_request_id:e,text:t.text,contact_id:t.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(n){e.debug("LeaveRequestAPI.update",n);var t=a.defer();return n.id||t.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",n).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,n,t){"use strict";t.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(t,a,o,s,i,r,c){function u(e){return p(e).then(function(e){var n=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=n,t.reject(e)}.bind(this))}.bind(this))}function l(){return c.all({id:this.type_id}).then(c.loadCalculationUnits).then(function(e){return t.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function m(){var n=[];return e.forEach(this.files,function(e){e.toBeDeleted&&n.push(r.deleteAttachment(this.id,e.attachment_id))}.bind(this)),t.all(n)}function f(e){return n.duration(e.time_to).subtract(n.duration(e.time_from)).asHours()}function p(n){return o.valuesOf("hrleaveandabsences_leave_request_status").then(function(t){return e.find(t,function(e){return e.name===n})})}function h(n){var a=e.cloneDeep(n),o=a.breakdown.length>1,s=e.first(e.values(a.breakdown)),i=e.last(e.values(a.breakdown));return t.all([this.getWorkDayForDate(s.date),o&&this.getWorkDayForDate(i.date)]).then(function(n){return s.amount=n[0].time_from?Math.min(this.from_date_amount,f(n[0])):0,o&&(i.amount=n[1].time_from?Math.min(this.to_date_amount,f(n[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,n){return e+n.amount},0),a}.bind(this))}function v(){var e=this.id,n=[];return n.push(t.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(n){return function(){return r.saveComment(e,n)}}))),n=n.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return r.deleteComment(e.comment_id)})),t.all(n)}return i.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(n){var t=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===n&&e.pull(t,"from_date_type","to_date_type"),r.calculateBalanceChange(e.pick(this,t)).then(function(e){return"hours"===n?h.call(this,e):e}.bind(this))},cancel:function(){return u.call(this,s.statusNames.cancelled)},approve:function(){return u.call(this,s.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return u.call(this,s.statusNames.rejected)},sendBack:function(){return u.call(this,s.statusNames.moreInformationRequired)},update:function(){return r.update(this.toAPI()).then(function(){return t.all([v.call(this),m.call(this)])}.bind(this))},create:function(){return r.create(this.toAPI()).then(function(e){return this.id=e.id,t.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(n){if(n.comment_id)return void(n.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return n.created_at===e.created_at&&n.text===e.text})},delete:function(){return r.delete(this.id)},getBalanceChangeBreakdown:function(){return r.getBalanceChangeBreakdown(this.id).then(function(n){return{amount:e.reduce(n.values,function(e,n){return e+parseFloat(n.amount)},0),breakdown:n.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return r.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return t.reject(e)})},isValid:function(){return r.isValid(this.toAPI())},isApproved:function(){return d.call(this,s.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,s.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,s.statusNames.cancelled)},isRejected:function(){return d.call(this,s.statusNames.rejected)},isSentBack:function(){return d.call(this,s.statusNames.moreInformationRequired)},loadComments:function(){return this.id?r.getComments(this.id).then(function(e){this.comments=e}.bind(this)):t.resolve()},roleOf:function(e){return this.contact_id===e?t.resolve("owner"):a(s.permissions.admin.administer).then(function(n){return n?"admin":r.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(n,t,a){e.includes(["balance_change","dates","comments","files"],a)||(n[a]=this[a])},loadAttachments:function(){return this.id?r.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):t.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,n,t,a){return e.debug("LeaveRequest"),n.extend({all:function(e,n,o,s,i){return t.all(this.processFilters(e),n,o,s,i).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,n,a,o){return t.balanceChangeByAbsenceType(e,n,a,o)},find:function(e){return t.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/instances/work-pattern.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("WorkPatternInstance",["$log","ModelInstance",function(e,n){return e.debug("WorkPatternInstance"),n.extend({})}])}),define("leave-absences/shared/models/work-pattern.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/work-pattern.instance"],function(e,n){"use strict";n.factory("WorkPattern",["$log","Model","WorkPatternAPI","WorkPatternInstance",function(n,t,a,o){return n.debug("WorkPattern"),t.extend({assignWorkPattern:function(e,n,t,o,s,i){return a.assignWorkPattern(e,n,t,o,s,i)},default:function(){return a.get({is_default:!0}).then(function(n){return o.init(e.first(n),!0)})},unassignWorkPattern:function(e){return a.unassignWorkPattern(e)},workPatternsOf:function(e,n,t){return a.workPatternsOf(e,n,t).then(function(e){return e.map(function(e){return o.init(e,!0)})})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,n,t){function a(t,a,o,s,i,r){function c(){return d().then(function(t){var a=t.filter(function(e){var t=e.info.details;return n(t.period_start_date).isSameOrBefore(v.selectedPeriod.end_date)&&(n(t.period_end_date).isSameOrAfter(v.selectedPeriod.start_date)||!t.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function u(){return{loadContacts:function(){var e=v.filters.userSettings.assignedTo.type;return m(e).then(function(e){v.lookupContacts=e}).then(function(){return"me"!==e?c():a.resolve(null)}).then(function(e){return v.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return o.all(f(),null,"display_name").then(function(e){return e.list})}function d(){return h?a.resolve(h):i.all()}function m(e){return"me"===e?o.leaveManagees(v.contactId):"unassigned"===e?o.leaveManagees(void 0,{unassigned:!0}):o.all().then(function(e){return e.list})}function f(){return{department:v.filters.userSettings.department?v.filters.userSettings.department.value:null,level_type:v.filters.userSettings.level_type?v.filters.userSettings.level_type.value:null,location:v.filters.userSettings.location?v.filters.userSettings.location.value:null,region:v.filters.userSettings.region?v.filters.userSettings.region.value:null,id:{IN:v.filters.userSettings.contact?[v.filters.userSettings.contact.id]:v.lookupContacts.map(function(e){return e.id})}}}function p(e){r.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}t.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,u()}}}t.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,n,t){function a(e,n,t){function a(){return{loadContacts:function(){return t.init({id:i.contactId}).leaveManagees().then(function(e){i.lookupContacts=e}).then(o)}}}function o(){return n.all(s(),null,"display_name").then(function(e){return e.list})}function s(){return{department:i.filters.userSettings.department?i.filters.userSettings.department.value:null,level_type:i.filters.userSettings.level_type?i.filters.userSettings.level_type.value:null,location:i.filters.userSettings.location?i.filters.userSettings.location.value:null,region:i.filters.userSettings.region?i.filters.userSettings.region.value:null,id:{IN:i.filters.userSettings.contact?[i.filters.userSettings.contact.id]:i.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var i;return{init:function(e){return i=e,i.showContactName=!0,i.showFilters=!0,a()}}}t.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,n,t){function a(e,n){function t(){return{loadContacts:function(){return n.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,t()}}}t.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,n,t,a){function o(a,o,s,i,r,c,u,l,d,m){function f(){for(var e=[],n=t(M.selectedPeriod.start_date).clone().startOf("month"),a=t(M.selectedPeriod.end_date).clone().endOf("month");n.isBefore(a);)e.push(A(n)),n.add(1,"month");M.months=e}function p(){i.$new().$watch(function(){return M.selectedMonths},function(n,t){null===t||e.equals(n,t)||I()})}function h(e){M.injectMonths=!0,S("injected").then(function(){I(e)}).then(function(){M.loading.calendar=!1})}function v(){k=a("LeaveCalendar"+n.capitalize(L)+"Controller").init(M)}function b(e){return e.current?"Current Period ("+e.title+")":e.title}function g(){return c.all().then(function(e){M.absencePeriods=n.sortBy(e,"start_date"),M.selectedPeriod=n.find(M.absencePeriods,function(e){return!!e.current})}).then(f).then(w)}function _(){return u.all().then(u.loadCalculationUnits)}function y(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return k.loadContacts().then(function(e){M.contacts=e})}function C(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){M.filters.optionValues.regions=e.hrjc_region,M.filters.optionValues.locations=e.hrjc_location,M.filters.optionValues.levelTypes=e.hrjc_level_type,M.filters.optionValues.departments=e.hrjc_department})}function T(){return l.all()}function D(){return o.all([_(),T(),y()]).then(function(e){M.supportData.absenceTypes=e[0],M.supportData.publicHolidays=e[1],M.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,M.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,M.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,M.supportData.toilAmounts=n.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function P(){var e=o.resolve();return M.injectMonths&&(e=S("destroyed"),M.injectMonths=!1),e}function A(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function R(e){e=n.includes(["contacts","period"],e)?e:"period",o.resolve().then(function(){M.loading.calendar=!0}).then(P).then("period"===e?f:n.noop).then("contacts"===e?q:n.noop).then(function(){h("contacts"===e)})}function I(e){var t=M.selectedMonths.length?M.months.filter(function(e){return n.includes(M.selectedMonths,e.index)}):M.months;i.$emit("LeaveCalendar::showMonths",t,!!e)}function w(){M.selectedMonths=[t().month()]}function O(){return M.roleOverride?o.resolve().then(function(){L=M.roleOverride}):o.all([m(r.permissions.admin.administer),m(r.permissions.ssp.manage)]).then(function(e){L=e[0]?"admin":e[1]?"manager":"staff"})}function S(e){return o(function(t){var a=0,o=i.$on("LeaveCalendar::month"+n.capitalize(e),function(){++a===M.months.length&&(o(),t())})})}s.debug("Component: leave-calendar");var k,L,M=this;M.absencePeriods=[],M.contacts=[],M.contactIdsToReduceTo=null,M.injectMonths=!1,M.months=[],M.selectedMonths=null,M.selectedPeriod=null,M.showContactName=!1,M.showFilters=!1,M.supportData={},M.loading={calendar:!0,page:!0},M.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},M.labelPeriod=b,M.refresh=R,function(){O().then(p).then(v).then(P).then(g).then(function(){return o.all([q(),D()])}).then(function(){return M.showFilters?C():n.noop}).then(function(){h()}).then(function(){M.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",o]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,n,t){function a(t,a,o,s){"use strict";function i(e,n,t,a,o){e.stopPropagation(),s.openModal(n,t,a,o)}function r(e){return e.isAM?"AM":e.isPM?"PM":""}function c(e){var t=n(e.from_date).isSame(b.date,"day"),a=n(e.to_date).isSame(b.date,"day");return t?n(e.from_date).format("HH:mm"):a?n(e.to_date).format("HH:mm"):""}function u(n,t){b.contactData.leaveRequestsAttributes[n.id].absenceTypeTitle=e.find(b.supportData.absenceTypes,{id:n.type_id}).title}function l(n,t){var a=e.find(b.supportData.absenceTypes,{id:n.type_id}),o=e.find(b.supportData.calculationUnits,{value:a.calculation_unit});t.unit=o.name}function d(e,n){n.from_date=new Date(e.from_date),n.to_date=new Date(e.to_date)}function m(n,t){"days"===t.unit&&(t.from_date_type=e.find(b.supportData.dayTypes,{value:n.from_date_type}).label,t.to_date_type=e.find(b.supportData.dayTypes,{value:n.to_date_type}).label)}function f(e,n){var t="";t=n.isAccruedTOIL?"AT":"days"===n.unit?r(n):c(e),n.label=t}function p(e){var n=b.contactData.leaveRequestsAttributes[e.id];[l,m,f,d,u].forEach(function(t){t.call(this,e,n)})}function h(e,n){o(function(){b.tooltip[e+"_hovered"]=n,b.tooltip.show=b.tooltip.day_cell_hovered||b.tooltip.tooltip_hovered},n?0:100)}function v(){a.$watch("day.contactData.leaveRequests",function(){b.contactData&&b.contactData.leaveRequests&&b.contactData.leaveRequests.forEach(p)},!0)}t.debug("Component: leave-calendar-day");var b=this;b.tooltip={show:!1,day_cell_hovered:!1,tooltip_hovered:!1},b.openLeavePopup=i,b.toggleTooltip=h,function(){v()}()}t.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){ +return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","$timeout","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function n(e){function n(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var t=this;t.legendCollapsed=!0,t.getAbsenceTypeStyle=n}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",n]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,n,t){function a(t,a,o,s,i,r,c){function u(e){q([e]),j(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(t){var a=n(),o=t.clone().startOf("month");return e.map(e.times(t.daysInMonth()),function(){var e={date:o.format("YYYY-MM-DD"),name:o.format("ddd"),index:o.format("D"),current:a.isSame(o,"day"),enabled:o.isSameOrAfter(V.period.start_date)&&o.isSameOrBefore(V.period.end_date),contactsData:{}};return o.add(1,"day"),e})}function m(e){return G[e]}function f(){return V.showOnlyWithLeaveRequests?V.contacts.filter(function(e){return Object.keys(Y[e.id]||{}).length}):V.contacts}function p(e){return n(e,c.serverDateFormat)}function h(e){var n=b(e);n&&(M(n),j(n))}function v(n){var t={request_type:"toil"};return e.some(n,t)&&!e.every(n,t)?e.filter(n,t):n}function b(n){var t;return e.find(Y[n.contact_id],function(a){return t=e.find(a,function(e){return+e.id==+n.id})}),t}function g(e){return CRM.url("civicrm/contact/view",{cid:e})}function _(e,t){var a={};return t.forEach(function(t){a[t.id]={styles:F(t),isAccruedTOIL:D(t,"toil"),isRequested:A(t),isAM:T("half_day_am",t,e.date),isPM:T("half_day_pm",t,e.date),isSingleDay:n(t.from_date).isSame(t.to_date,"day")}}),a}function y(){V.supportData.dayTypes=e.indexBy(V.supportData.dayTypes,"name"),V.supportData.leaveRequestStatuses=e.indexBy(V.supportData.leaveRequestStatuses,"value"),V.supportData.publicHolidays=e.transform(V.supportData.publicHolidays,function(e,n){e[p(n.date).valueOf()]=n},{})}function q(e){return e.forEach(function(e){var n=R(e);Y[e.contact_id]=Y[e.contact_id]||{},n.forEach(function(n){Y[e.contact_id][n.date]||(Y[e.contact_id][n.date]=[]),Y[e.contact_id][n.date].push(e)})}),a.resolve()}function C(){H.push(o.$on("LeaveCalendar::showMonths",B)),H.push(r.subscribe("LeaveRequest::new",u)),H.push(r.subscribe("LeaveRequest::edit",N)),H.push(r.subscribe("LeaveRequest::updatedByManager",N)),H.push(r.subscribe("LeaveRequest::delete",h)),H.push(r.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):N(e.leaveRequest)}))}function T(e,t,a){var o=V.supportData.dayTypes[e];return n(a).isSame(t.from_date,"day")?o.value===t.from_date_type:n(a).isSame(t.to_date,"day")?o.value===t.to_date_type:void 0}function D(e,n){return e.request_type===n}function P(e){return!!V.supportData.publicHolidays[p(e).valueOf()]}function A(n){var t=V.supportData.leaveRequestStatuses[n.status_id].name;return e.contains([c.statusNames.awaitingApproval,c.statusNames.moreInformationRequired],t)}function R(t){for(var a=[],o=n(t.from_date).clone(),s=n(t.to_date);o.isSameOrBefore(s);)o.month()===V.month.index&&o.year()===V.month.year&&a.push(e.find(V.month.days,function(e){return e.date===o.format("YYYY-MM-DD")})),o.add(1,"day");return a}function I(n){var t=e.find(V.supportData.leaveRequestStatuses,function(e){return e.name===n});return t?t.value:null}function w(){return[I(c.statusNames.approved),I(c.statusNames.adminApproved),I(c.statusNames.awaitingApproval),I(c.statusNames.moreInformationRequired)]}function O(){return V.month.loading=!0,a.all([k(),S()]).then(L).then(E).then(function(){W=!0,V.month.loading=!1})}function S(){return i.all({from_date:{to:V.month.days[V.month.days.length-1].date},to_date:{from:V.month.days[0].date},status_id:{IN:w()},contact_id:{IN:V.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(V.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return q(e.list)})}function k(){var n=V.month.days[0].date,t=V.month.days[V.month.days.length-1].date;return s.get(V.contacts.map(function(e){return e.id}),n,t).then(function(n){G=e.indexBy(n,"contact_id")})}function L(){return V.contactIdsToReduceTo&&(V.contacts=V.contacts.filter(function(n){return e.includes(V.contactIdsToReduceTo,n.contact_id)||e.find(Y,function(e){return e.contact_id===n.contact_id})})),a.resolve()}function M(n){var t=R(n);Y[n.contact_id]=Y[n.contact_id]||{},t.forEach(function(t){e.remove(Y[n.contact_id][t.date],function(e){return e.id===n.id})})}function x(){o.$emit("LeaveCalendar::monthDestroyed"),H.map(function(e){e.remove?e.remove():e()})}function $(n,t,o){var s,i;return n.contactsData[t]=n.contactsData[t]||{},i=m(t),s=!0===o?a.resolve():a.all([i.isWeekend(p(n.date)),i.isNonWorkingDay(p(n.date))]).then(function(a){e.assign(n.contactsData[t],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:P(n.date)})}),s.then(function(){return Y[t]&&Y[t][n.date]?Y[t][n.date]:[]}).then(function(a){a=U(a),e.assign(n.contactsData[t],{leaveRequests:a,leaveRequestsToShowInCell:v(a),leaveRequestsAttributes:_(n,a)})})}function E(){return a.all(V.month.days.map(function(e){return a.all(V.contacts.map(function(n){return $(e,n.id)}))}))}function B(n,t,a){!e.find(t,function(e){return e.index===V.month.index})?V.visible=!1:(V.currentPage=0,V.visible=!0,(a||!W)&&O())}function U(t){return e.sortBy(t,function(e){return+n(e.from_date).format("X")+(T("half_day_pm",e,e.from_date)?1:0)})}function F(n){var t=e.find(V.supportData.absenceTypes,function(e){return e.id===n.type_id});return n.balance_change>0?{borderColor:t.color}:{borderColor:t.color,backgroundColor:t.color}}function N(e){h(e),-1!==w().indexOf(e.status_id)&&u(e)}function j(e){return a.all(R(e).map(function(n){return $(n,e.contact_id,!0)}))}t.debug("Component: leave-calendar-month");var W=!1,H=[],G={},Y={},V=this;V.currentPage=0,V.pageSize=20,V.visible=!1,V.showContactName=!!V.showContactName,V.showOnlyWithLeaveRequests=!!V.showOnlyWithLeaveRequests,V.$onDestroy=x,V.contactsList=f,V.getContactUrl=g,function(){var e=n().month(V.month.index).year(V.month.year);y(),C(),V.month=l(e),o.$emit("LeaveCalendar::monthInjected")}()}t.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,n){"use strict";function t(n,t,a){function o(){var n=t.defer();return a.open(e.defaults(s(),{onConfirm:function(){n.resolve(!0)}})),n.promise}function s(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return n.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:s,promptBalanceChangeRecalculation:o}}n.factory("LeaveRequestService",t),t.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,n,t){function a(t,a,o,s,i,r,c,u){function l(n){y=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],n)||"toil"===q.leaveRequest.request_type?o.open(h(n)):f(n)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function m(t){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||("manager"===q.role?e.includes([C.awaitingApproval,C.moreInformationRequired],t):"3"===a?n().isBefore(q.leaveRequest.from_date):"2"===a)}function f(n){o.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(t){return t?e.assign(i.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){s.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(n)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var n=T[e].dialog;return{title:"Confirm "+n.title+"?",copyCancel:"Cancel",copyConfirm:n.btnLabel,classConfirm:"btn-"+n.btnClass,msg:n.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){b(e)}).catch(function(e){u.error("Error:",e)})}}}function v(e,n,t,a,o){e.stopPropagation(),s.openModal(n,t,a,o)}function b(n){var t=e.find(q.leaveRequestStatuses,function(e){return e.name===c.statusNames.awaitingApproval}).value;y===t&&r.publish("ManagerBadge:: Update Count"),r.publish("LeaveRequest::statusUpdate",{status:n,leaveRequest:q.leaveRequest})}function g(){var n=q.leaveRequestStatuses[q.leaveRequest.status_id].name,t=e.compact(e.map(T,function(t,a){return e.includes(t.allowedStatuses,n)?a:null}));!m(n)&&e.pull(t,"cancel"),"admin"!==q.role&&e.pull(t,"delete"),"staff"===q.role&&e.pull(t,"approve","reject"),"staff"!==q.role&&_(t),d()&&t.push("delete"),q.allowedActions=e.map(t,function(e){return{key:e,label:T[e].label,isDirectAction:T[e].isDirectAction}})}function _(n){e.each(n,function(t,a){"edit"===t&&(n[a]="respond"),e.includes(["respond","view"],t)&&(n[a]="edit")})}t.debug("Component: leave-request-action-dropdown");var y,q=this,C=c.statusNames,T={edit:{label:"Edit",allowedStatuses:[C.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[C.moreInformationRequired]},view:{label:"View",allowedStatuses:[C.approved,C.rejected,C.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[C.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[C.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[C.awaitingApproval,C.approved,C.rejected,C.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[C.awaitingApproval,C.moreInformationRequired,C.approved,C.rejected,C.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),g()}()}t.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,n,t){function a(t,a,o,s,i,r,c){function u(){q.request.comments.push({contact_id:y,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function m(e){return n.utc(e,i.serverDateTimeFormat).local().format(s.DATE_FORMAT.toUpperCase()+" HH:mm")}function f(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===y?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function b(){var n=e.indexBy(q.request.comments,"contact_id"),t=Object.keys(n);return r.all({id:{IN:t}},{page:1,size:0}).then(function(n){q.comment.contacts=e.indexBy(n.list,"contact_id")})}function g(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&b()})}function _(){return q.loading.component=!0,c.get().then(function(e){y=e.contactId}).then(function(){q.loading.component=!1})}t.debug("Component: leave-request-popup-comments-tab");var y=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=u,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=m,q.getActiveComments=f,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){o.$emit("LeaveRequestPopup::addTab",q),g(),_()}()}t.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,n,t){function a(t,a,o,s,i,r,c,u,l,d,m){function f(){ne.balance.closing=ne.balance.opening+ne.balance.change.amount}function p(e){return n(e,c.serverDateFormat).toDate()}function h(e){return n(e).format(c.serverDateFormat)}function v(e){var n;return i.resolve().then(function(){N(e),"from"===e&&F(),S("hours")&&(_(e),"from"!==e||ne.uiOptions.multipleDays||_("to")),ne.loading[e+"DayTypes"]=!0}).then(function(){return q(e)}).then(function(e){if(n=e.id!==ne.period.id,n&&(ne.period=e),!ne.period.id)return i.reject("Please change date as it is not in any absence period")}).then(W).then(function(){if(n)return x()}).then(function(){return ne.onDateChangeExtended&&ne.onDateChangeExtended(e)}).then(function(){if(V(),!n)return E();o.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(P).finally(y)}function b(){return V(),E()}function g(){return ne.uiOptions.toDate=null,N("to"),i.resolve().then(V).then(ne.setDaysSelectionModeExtended).then(y).then(!ne.uiOptions.multipleDays&&E)}function _(e){ne.uiOptions.times[e].loading=!0}function y(){["from","to"].forEach(function(e){ne.loading[e+"DayTypes"]=!1,S("hours")&&(ne.uiOptions.times[e].loading=!1)})}function q(t){var a=n(ne.uiOptions[t+"Date"]).format(ne.uiOptions.userDateFormat.toUpperCase());return e.find(ne.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function C(){return ne.request?ne.request.request_type:ne.leaveType||null}function T(e){return n().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function D(){return z(),ne.loading.balanceChange=!0,ne.request.getBalanceChangeBreakdown().then(j).catch(P)}function P(n){o.$broadcast("LeaveRequestPopup::handleError",e.isArray(n)?n:[n]),ne.loading.fromDayTypes=!1,ne.loading.balanceChange=!1,ne.loading.tab=!1,ne.loading.toDayTypes=!1}function A(){return ne.isMode("create")||ne.forceRecalculateBalanceChange?E():D()}function R(){var e=ne.request.attributes();return ne.uiOptions.fromDate=p(ne.request.from_date),ne.request.to_date=e.to_date,ne.request.to_date_type=e.to_date_type,ne.uiOptions.toDate=p(ne.request.to_date),ne.initDayTypesExtended?ne.initDayTypesExtended():i.resolve()}function I(){ee.push(o.$on("LeaveRequestPopup::absenceTypeChanged",function(){Q()}),o.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,n){J(n)}),o.$on("LeaveRequestPopup::recalculateBalanceChange",E))}function w(){ne.isMode("edit")&&(ne.isLeaveStatus(c.statusNames.approved)||ne.isLeaveStatus(c.statusNames.adminApproved))&&(Z={absenceTypeId:ne.request.type_id,value:ne.selectedAbsenceType.remainder-ne.request.balance_change})}function O(){o.$watch(function(){return ne.uiOptions.times.from.time},function(e,n){e!==n&&(ne.uiOptions.multipleDays||(K(e),V()))})}function S(e){return ne.selectedAbsenceType.calculation_unit_name===e}function k(e){return ne.request.request_type===e}function L(n){return e.includes(["weekend","non_working_day","public_holiday"],n)}function M(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){ne.requestDayTypes=e})}function x(){return u.get(ne.request.contact_id,ne.period.start_date,ne.period.end_date).then(function(e){ne.calendar=e})}function $(){var e=(ne.pagination.currentPage-1)*ne.pagination.numPerPage,n=e+ne.pagination.numPerPage;ne.pagination.filteredbreakdown=ne.balance.change.breakdown.slice(e,n)}function E(){return z(),ne.canCalculateChange()?(ne.loading.balanceChange=!0,ne.request.change_balance=!0,ne.calculateBalanceChange().then(j).catch(P).finally(function(){ne.loading.balanceChange=!1})):i.resolve()}function B(){ne.pagination.totalItems=ne.balance.change.breakdown.length,ne.pagination.filteredbreakdown=ne.balance.change.breakdown,ne.pagination.pageChanged()}function U(){return h(ne.request.from_date)===h(ne.request.to_date)}function F(){ne.uiOptions.toDate&&ne.uiOptions.fromDate&&ne.uiOptions.multipleDays&&n(ne.uiOptions.toDate).isSameOrBefore(ne.uiOptions.fromDate)&&(ne.uiOptions.toDate=null,N("to"))}function N(e){ne.resetUIInputsExtended&&ne.resetUIInputsExtended(e),V(),z()}function j(e){ne.balance.change=e,ne.request.balance_change=e.amount,f(),B(),ne.loading.balanceChange=!1}function W(){var e,t,a;ne.uiOptions.fromDate?(e=n(ne.uiOptions.fromDate).add(1,"day").toDate(),a=e,t=e):(a=p(ne.period.start_date),t=ne.uiOptions.date.to.options.minDate),ne.uiOptions.date.to.options.initDate=t,ne.uiOptions.date.to.options.minDate=a,ne.uiOptions.date.to.options.maxDate=p(ne.period.end_date)}function H(){return!ne.isMode("create")&&U()||ne.isMode("create")&&(k("sickness")||S("hours"))?ne.uiOptions.multipleDays=!1:ne.uiOptions.multipleDays=!0,i.resolve().then(ne.setDaysSelectionModeExtended)}function G(){Z&&Z.absenceTypeId===ne.selectedAbsenceType.id?ne.balance.opening=Z.value||0:ne.balance.opening=ne.selectedAbsenceType.remainder}function Y(){ne.selectedAbsenceType=e.find(ne.absenceTypes,function(e){return e.id===ne.request.type_id})}function V(){var e=ne.uiOptions,n=e.times;ne.request.from_date=e.fromDate?h(e.fromDate):null,ne.request.to_date=e.toDate?h(e.toDate):null,!e.multipleDays&&e.fromDate&&(ne.request.to_date=ne.request.from_date,ne.request.to_date_type=ne.request.from_date_type),(S("hours")||k("toil"))&&(ne.request.from_date=ne.request.from_date&&n.from.time?ne.request.from_date+" "+n.from.time:null,ne.request.to_date=ne.request.to_date&&n.to.time?ne.request.to_date+" "+n.to.time:null)}function z(){ne.uiOptions.showBalance=ne.canCalculateChange()}function X(){e.forEach(ee,function(e){e()})}function Q(){var e,n=ne.selectedAbsenceType.calculation_unit_name;return Y(),e=n!==ne.selectedAbsenceType.calculation_unit_name,G(),i.resolve().then(e&&H).then(e&&ne.onAbsenceTypeUpdateExtended).then(e&&V).then(y).then(E)}function J(e){return ne.absenceTypes=e,Y(),n(ne.uiOptions.toDate).isAfter(ne.period.end_date)&&(ne.uiOptions.toDate=void 0,N("to")),G(),E()}function K(e){var n=T(e).add(ne.uiOptions.time_interval,"minutes");n.isAfter(T(ne.uiOptions.times.to.max))||(ne.uiOptions.times.to.min=n.format("HH:mm"),n.isAfter(T(ne.uiOptions.times.to.time))&&(ne.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var Z=null,ee=[],ne=this;ne.canManage=!1,ne.calendar={},ne.errors=[],ne.isRequired=!0,ne.requestDayTypes=[],ne.statusNames=c.statusNames,ne.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},ne.pagination={currentPage:1,filteredbreakdown:ne.balance.change.breakdown,numPerPage:7,totalItems:ne.balance.change.breakdown.length,pageChanged:$},ne.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:r.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},ne.convertDateFormatFromServer=p,ne.convertDateToServerFormat=h,ne.dateChangeHandler=v,ne.dateTypeChangeHandler=b,ne.daysSelectionModeChangeHandler=g,ne.disableAndShowLoadingTimeInput=_,ne.getMomentDateWithGivenTime=T,ne.handleError=P,ne.isCalculationUnit=S,ne.isLeaveType=k,ne.isNotWorkingDay=L,ne.performBalanceChangeCalculation=E,ne.setRequestDateTimesAndDateTypes=V,ne.updateEndTimeInputMinTime=K,ne.$onDestroy=X,function(){t("RequestModalDetails"+e.capitalize(C(ne.leaveType,ne.request))+"Controller",{detailsController:ne}),ne.canManage=ne.isRole("manager")||ne.isRole("admin"),ne.loading.tab=!0,s.$emit("LeaveRequestPopup::addTab",ne),I(),ne.initChildController().then(function(){return i.all([x(),M()])}).then(!ne.isMode("create")&&R).then(H).then(function(){if(!ne.isMode("create"))return i.resolve().then(ne.initTimesExtended).then(V)}).then(!ne.isMode("create")&&W).then(w).then(G).then(A).then(O).then(!ne.isMode("view")&&ne.initWatchersExtended).catch(P).finally(function(){ne.loading.tab=!1})}()}t.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,n,t){function a(t,a,o,s,i,r,c,u,l){function d(){return O.fileUploader&&O.fileUploader.queue.length>0}function m(){return O.getFilesAmount()0?R.map(function(e){return e.label}).join(", "):""}function q(){return O.request.loadAttachments().then(function(){o.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function C(){return a.all(R.map(function(e){return l.getMimeTypeFor(e.label).then(function(n){w[e.label]=n})})).catch(function(){w=null})}function T(){return c.valuesOf("safe_file_extension").then(function(e){R=e})}function D(e){return!e.attachment_id||O.canManage}function P(){e.forEach(I,function(e){e()})}function A(e,n){O.fileUploader.queue&&O.fileUploader.queue.length>0?O.fileUploader.uploadAll({entityID:O.request.id}).then(function(){n()}).catch(n):n()}t.debug("Component: leave-request-popup-files-tab");var R=[],I=[],w={},O=Object.create(this);return O.filesLoaded=!1,O.fileUploader=null,O.today=Date.now(),O.userDateFormatWithTime=i.DATE_FORMAT+" HH:mm",O.userDateFormat=i.DATE_FORMAT,O.$onDestroy=P,O.canRemoveAttachment=D,O.canSubmit=d,O.canUploadMore=m,O.formatDateTime=f,O.getAuthorName=p,O.getFilesAmount=h,O.listFileTypes=y,function(){o.$broadcast("LeaveRequestPopup::childComponent::register"),s.$emit("LeaveRequestPopup::addTab",O),g(),a.all([T(),q()]).then(_).finally(function(){O.filesLoaded=!0})}(),O}t.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function n(e,n,t){function a(e,t,a,o){n.openModal.apply(n,arguments)}e.debug("Component: leave-request-record-actions");var o,s=this;s.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"}],s.openLeavePopup=a,function(){o=t.parse(),o.openModal&&a(null,o.openModal,s.selectedContactId,s.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{contactId:"<",isSelfRecord:"<",selectedContactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",n]})}),define("leave-absences/shared/components/staff-leave-report.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,n,t){function a(n,t,a,o,s,i,r,c,u,l,d,m){function f(e,n){n.data.push(e),n.dataIndex[e.id]=e}function p(e){E(e),W.sections.other.open&&f(e,W.sections.other)}function h(){Object.values(W.sections).forEach(function(e){e.data=[]})}function v(e){var n=j[e.status];n?n(e.leaveRequest):W.refresh()}function b(n){n.dataIndex=e.indexBy(n.data,"id")}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function _(){return s.all().then(function(n){W.absencePeriods=e.sortBy(n,"start_date"),W.selectedPeriod=e.find(W.absencePeriods,function(e){return!0===e.current})})}function y(){return i.all().then(i.loadCalculationUnits).then(function(n){W.absenceTypes=n,W.absenceTypesIndexed=e.indexBy(n,"id")})}function q(){return R("approved",{status_id:N(m.statusNames.approved)})}function C(){return t.all([c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,null,!0),c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,[N(m.statusNames.approved)]),c.balanceChangeByAbsenceType(W.contactId,W.selectedPeriod.id,[N(m.statusNames.awaitingApproval),N(m.statusNames.moreInformationRequired)])]).then(function(e){W.absenceTypes.forEach(function(n){n.balanceChanges={holidays:e[0][n.id],approved:e[1][n.id],pending:e[2][n.id]}})})}function T(){return r.all({contact_id:W.contactId,period_id:W.selectedPeriod.id},!0).then(function(e){W.entitlements=e}).then(function(){W.absenceTypesFiltered=W.absenceTypes.filter(function(n){var t=e.find(W.entitlements,function(e){return e.type_id===n.id});return n.entitlement=t?t.value:0,n.remainder=t?t.remainder:{current:0,future:0},!(0===n.entitlement&&"1"!==n.allow_overuse&&"1"!==n.allow_accruals_request)})})}function D(){return r.breakdown({contact_id:W.contactId,period_id:W.selectedPeriod.id},W.entitlements).then(function(){return M(W.entitlements)}).then(function(e){W.sections.entitlements.data=e})}function P(){return t.all([r.breakdown({contact_id:W.contactId,period_id:W.selectedPeriod.id,expired:!0}),A({request_type:"toil",expired:!0})]).then(function(e){return t.all({expiredBalanceChangesFlatten:M(e[0]),expiredTOILS:x(e[1].list)})}).then(function(n){W.sections.expired.data=n.expiredBalanceChangesFlatten.concat(n.expiredTOILS),W.sections.expired.data=e.sortBy(W.sections.expired.data,"expiry_date")})}function A(n){return c.all(e.assign({contact_id:W.contactId,from_date:{from:W.selectedPeriod.start_date},to_date:{to:W.selectedPeriod.end_date},type_id:{IN:W.absenceTypes.map(function(e){return e.id})}},n),null,"from_date ASC",null,!1)}function R(e,n){return A(n).then(function(n){W.sections[e].data=n.list})}function I(){return t.all(Object.values(W.sections).filter(function(e){return e.open}).map(k))}function w(){return R("other",{status_id:{in:[N(m.statusNames.rejected),N(m.statusNames.cancelled)]}})}function O(){return R("pending",{status_id:{in:[N(m.statusNames.awaitingApproval),N(m.statusNames.moreInformationRequired)]}})}function S(){return R("holidays",{public_holiday:!0})}function k(e){return e.loading=!0,e.loadLeaveRequests().then(b.bind(this,e)).then(function(){e.loading=!1})}function L(){return u.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){W.leaveRequestStatuses=e.indexBy(n,"value")})}function M(n){return t.resolve().then(function(){return n.map(function(n){var t=e.find(W.entitlements,function(e){return e.id===n.id});return n.breakdown.map(function(n){return e.assign(e.clone(n),{type_id:t.type_id})})})}).then(function(e){return Array.prototype.concat.apply([],e)})}function x(e){return t.resolve().then(function(){return e.map(function(e){return{expiry_date:e.toil_expiry_date,type:{label:"Accrued TOIL"}}})})}function $(){l.subscribe("LeaveRequest::new",function(){W.refresh()}),l.subscribe("LeaveRequest::edit",function(){W.refresh()}),l.subscribe("LeaveRequest::statusUpdate",v),l.subscribe("LeaveRequest::delete",function(e){E(e)})}function E(n){e.forEach(W.sections,function(t,a){t.dataIndex[n.id]&&(e.remove(t.data,function(e){return e.id===n.id}),delete t.dataIndex[n.id],"other"!==a&&B(n,a))})}function B(n,t){var a=["future","current"],o=W.absenceTypesIndexed[n.type_id];"pending"===t&&e.pull(a,"current"),o.balanceChanges[t]-=n.balance_change,a.forEach(function(e){o.remainder[e]-=n.balance_change})}function U(){W.loading.content=!0,t.all([T(),C()]).then(function(){W.loading.content=!1}).then(function(){return t.all([I(),h()])})}function F(e){var n=W.sections[e];n.open=!n.open,n.open&&!n.data.length&&k(n)}function N(n){return e.find(W.leaveRequestStatuses,function(e){return e.name===n}).value}n.debug("Component: staff-leave-report");var j={delete:E,cancel:p},W=this;W.absencePeriods=[],W.absenceTypes=[],W.absenceTypesFiltered=[],W.absenceTypesIndexed={},W.dateFormat=d.DATE_FORMAT,W.leaveRequestStatuses={},W.selectedPeriod=null,W.role="absence-tab"===a.section?"admin":"staff",W.loading={content:!0,page:!0},W.sections={approved:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:q},entitlements:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:D},expired:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:P},holidays:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:S},pending:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:O},other:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:w}},W.labelPeriod=g,W.refresh=U,W.toggleSection=F,function(){t.all([L(),y(),_()]).then(function(){W.loading.page=!1}).then(function(){return t.all([T(),C()])}).then(function(){W.loading.content=!1}),$()}()}t.component("staffLeaveReport",{bindings:{contactId:"<"}, +templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/staff-leave-report.html"}],controllerAs:"report",controller:["$log","$q","$rootScope","checkPermissions","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","OptionGroup","pubSub","HR_settings","shared-settings",a]})}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,n,t){function a(t,a,o,s,i,r,c){function u(){return i.request.calculateBalanceChange(i.selectedAbsenceType.calculation_unit_name)}function l(){var e=i.request,n=!!e.from_date&&!!e.to_date,t=i.selectedAbsenceType.calculation_unit_name;return"days"===t?n=n&&!!e.from_date_type&&!!e.to_date_type:"hours"===t&&(n=n&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),n}function d(){return i.canCalculateChange()}function m(n,t){var a=i.uiOptions.times[n],o=e.clone(t.time_from),s=e.clone(t.time_to);i.uiOptions.multipleDays||("from"===n&&s&&o&&(s=i.getMomentDateWithGivenTime(s).subtract(i.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===n&&o&&s&&(o=i.getMomentDateWithGivenTime(o).add(i.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=o||"00:00",a.max=s||"00:00",a.time="to"===n?a.max:a.min}function f(n,t){return n?(n=i.convertDateToServerFormat(n),v(n).then(function(t){return t?i.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):p(n,i.requestDayTypes).then(function(n){return n.length?n:i.requestDayTypes.filter(function(n){return e.includes(["all_day","half_day_am","half_day_pm"],n.name)})})}).then(function(e){return I(t,e),e})):o.reject([])}function p(e,t){return e=n(e),o.all([i.calendar.isNonWorkingDay(e),i.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?t.filter(function(n){return n.name===e}):[]})}function h(e,t){return n.duration(t).subtract(n.duration(e)).asHours()}function v(e){return c.all({public_holiday:1,contact_id:i.request.contact_id,from_date:{from:e},to_date:{to:e}}).then(function(e){return!!e.list.length})}function b(){return o.resolve()}function g(){return D(i.uiOptions.fromDate,"from").then(function(){return D(i.uiOptions.toDate,"to")})}function _(e){s.$watch(function(){return i.uiOptions.times[e].amount},function(e,n){i.isCalculationUnit("days")||+e==+n||(i.isRole("staff")&&(i.request.change_balance=!0),S(),i.performBalanceChangeCalculation())})}function y(e){var t=n(i.request[e+"_date"]).format("HH:mm"),a=i.uiOptions.times[e];(h(a.min,t)<=0||h(a.max,t)>=0)&&(t="from"===e?a.min:a.max),i.uiOptions.times[e].time=t}function q(){var e=i.uiOptions.multipleDays?["from","to"]:["from"],n=i.uiOptions.times;if(i.isCalculationUnit("hours"))return o.all(e.map(A)).then(function(){["from","to"].forEach(function(e){y(e),O(e),n[e].amount=Math.min(i.request[e+"_date_amount"],n[e].maxAmount).toString()}),i.uiOptions.multipleDays||i.updateEndTimeInputMinTime(i.uiOptions.times.from.time)}).then(S)}function C(){["from","to"].forEach(function(e){_(e),T(e)})}function T(e){s.$watch(function(){return i.uiOptions.times[e].time},function(n,t){i.isCalculationUnit("days")||n===t||(i.setRequestDateTimesAndDateTypes(),n&&O(e,!0))})}function D(e,n){return f(e,n).then(function(){i.loading[n+"DayTypes"]=!1})}function P(e){return D(i.uiOptions[e+"Date"],e).then(function(){if(i.isCalculationUnit("hours"))return A(e).then(function(){O(e,!0)})})}function A(e){var n=i.uiOptions[e+"Date"],t=!i.uiOptions.multipleDays;return n?i.request.getWorkDayForDate(i.convertDateToServerFormat(n)).then(function(n){L[e]=n,m(e,n),t&&"from"===e&&m("to",n)}).catch(function(n){return L[e]={},i.handleError(n)}).finally(function(){i.uiOptions.times[e].loading=!1,t&&(i.uiOptions.times.to.loading=!1)}):o.resolve()}function R(n){var t=i.uiOptions.times[n];i["request"+e.startCase(n)+"DayTypes"]=[],t.time="",t.min="00:00",t.max="00:00",t.amount="0",t.maxAmount="0"}function I(n,t){var a="request"+e.startCase(n)+"DayTypes";i[a]=t,i.isMode("create")&&(i.request[n+"_date_type"]=i[a][0].value)}function w(){return i.isCalculationUnit("hours")&&i.uiOptions.fromDate?(i.disableAndShowLoadingTimeInput("from"),!i.uiOptions.multipleDays&&i.disableAndShowLoadingTimeInput("to"),A("from").then(function(){O("from",!0)})):o.resolve()}function O(e,n){var t=i.uiOptions,a=t.multipleDays?e:"from",o=t.times[a],s=t.multipleDays&&"to"===a?o.min:t.times.from.time,r=t.multipleDays&&"from"===a?o.max:t.times.to.time,c=L[a].number_of_hours?h(s,r).toString():"0";o.maxAmount=c,n&&(o.amount=o.maxAmount)}function S(){var e=i.uiOptions.times;i.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,i.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function k(){return i.isCalculationUnit("hours")&&i.uiOptions.fromDate?A("from").then(function(){O("from",!0)}):o.resolve()}var L={};a.debug("RequestModalDetailsLeaveController"),i.calculateBalanceChange=u,i.canCalculateChange=l,i.canSubmit=d,i.initChildController=b,i.initDayTypesExtended=g,i.initTimesExtended=q,i.initWatchersExtended=C,i.onAbsenceTypeUpdateExtended=k,i.onDateChangeExtended=P,i.resetUIInputsExtended=R,i.setDaysSelectionModeExtended=w}t.controller("RequestModalDetailsLeaveController",a),a.$inject=["$controller","$log","$q","$rootScope","detailsController","PublicHoliday","LeaveRequest"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,n){function t(n,t,a,o,s,i,r){function c(){return!(!r.canCalculateChange()||!r.request.sickness_reason)}function u(){return a.all([m(),h(),f(!0)])}function l(n){var t=r.request.getDocumentArray();return!!e.find(t,function(e){return e===n})}function d(n){return!!e.find(r.sicknessDocumentTypes,function(e){return e.value===n})}function m(){return i.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){r.sicknessDocumentTypes=e})}function f(n){return i.valuesOf("hrleaveandabsences_sickness_reason",n).then(function(n){r.sicknessReasons=e.indexBy(n,"name")})}function p(){s.loadForm("/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1").on("crmUnload",function(){f(!1)})}function h(){r.showSicknessOptionsEditorIcon=e.includes(["admin-dashboard","absence-tab"],o.section)}t.debug("RequestModalDetailsSicknessController"),n("RequestModalDetailsLeaveController",{detailsController:r}),r.canSubmit=c,r.initChildController=u,r.isChecked=l,r.isDocumentInRequest=d,r.openSicknessReasonOptionsEditor=p}n.controller("RequestModalDetailsSicknessController",t),t.$inject=["$controller","$log","$q","$rootScope","crmAngService","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,n,t){function a(t,a,o,s,i,r,c){function u(){return c.balance.change.amount=+c.request.toil_to_accrue,a.resolve(c.balance.change)}function l(){if(!c.request.from_date||!c.request.to_date)return c.uiOptions.max_toil_duration_and_accrual=null,void(c.uiOptions.toil_duration_in_hours=null);c.uiOptions.max_toil_duration_and_accrual=n.duration(n(c.request.to_date).diff(c.request.from_date)).asHours()}function d(){return v().catch(function(e){return e.length&&(c.errors=e),a.reject(e)}).then(function(e){return r.calculateToilExpiryDate(c.request.type_id,e)}).then(function(e){return c.request.toil_expiry_date=e,c.uiOptions.expiryDate=new Date(e),e})}function m(){return!!c.request.toil_to_accrue}function f(){var e=c.uiOptions.multipleDays&&!!c.request.to_date,n=!c.uiOptions.multipleDays&&!!c.request.from_date,t=n||e,a=N.from_date!==c.request.from_date||N.to_date!==c.request.to_date;return c.canDisplayToilExpirationField&&t&&W.hasExpirationFromAdminSettings&&a}function p(){return!!(c.request.from_date&&c.request.to_date&&c.request.toil_duration&&c.request.toil_to_accrue)}function h(){c.request.toil_expiry_date=!1,c.uiOptions.expiryDate=null}function v(){var e=c.uiOptions.multipleDays,n=c.request;return b({hasErrors:e?!n.to_date&&!n.from_date:!n.from_date,label:e?"To Date":"From Date",value:n.to_date})}function b(e){if(e.hasErrors){var t="Please select "+e.label+" to find expiry date";return a.reject([t])}return e.value?a.resolve(n(e.value).format("YYYY-MM-DD")):a.reject([])}function g(){var e=c.isMode("create")&&W.hasExpirationFromAdminSettings,n=W.hasPreviousExpirationDate,t=c.isLeaveType("toil"),a=c.canManage;c.canDisplayToilExpirationField=t&&(a||e||n)}function _(){c.uiOptions.toil_duration_in_hours=c.request.toil_duration/60}function y(){return W.hasPreviousExpirationDate=c.isMode("edit")&&!!c.request.toil_expiry_date,r.canExpire(c.request.type_id).then(function(e){W.hasExpirationFromAdminSettings=e})}function q(){return c.request.to_date_type=c.request.from_date_type="1",y().then(g).then(C).then(I)}function C(){c.canManage&&(c.uiOptions.expiryDate=c.convertDateFormatFromServer(c.request.toil_expiry_date))}function T(){o.$watch(function(){return c.request.toil_to_accrue},function(e,n){+e!=+n&&c.performBalanceChangeCalculation()})}function D(){o.$watch(function(){return c.uiOptions.toil_duration_in_hours},function(e,n){e!==n&&c.isCalculationUnit("hours")&&k(),c.request.toil_duration=c.uiOptions.toil_duration_in_hours?60*c.uiOptions.toil_duration_in_hours:null})}function P(){var e=c.uiOptions.times;e.from.time=n(c.request.from_date).format("HH:mm"),e.to.time=n(c.request.to_date).format("HH:mm"),c.uiOptions.multipleDays||c.updateEndTimeInputMinTime(c.uiOptions.times.from.time)}function A(){["from","to"].forEach(function(e){o.$watch(function(){return c.uiOptions.times[e].time},function(e,n){e!==n&&(c.setRequestDateTimesAndDateTypes(),U(),l(),L())})})}function R(){c.isMode("view")||(T(),D(),A())}function I(n){return i.valuesOf("hrleaveandabsences_toil_amounts",n).then(function(n){c.toilAmounts=e.sortBy(n,function(e){return+e.weight})})}function w(){return l(),L(),U()}function O(){return x(),c.uiOptions.multipleDays||c.updateEndTimeInputMinTime(c.uiOptions.times.from.time),l(),j?j=!1:L(),U()}function S(e){c.uiOptions.times[e].time=""}function k(){c.request.toil_to_accrue=c.uiOptions.toil_duration_in_hours}function L(){c.uiOptions.toil_duration_in_hours=c.uiOptions.max_toil_duration_and_accrual}function M(){N=e.cloneDeep(c.request.attributes())}function x(){c.uiOptions.multipleDays?["from","to"].forEach(function(e){c.uiOptions.times[e].min="00:00",c.uiOptions.times[e].max="23:45"}):(c.uiOptions.times.from.min="00:00",c.uiOptions.times.from.max="23:30",c.uiOptions.times.to.min="00:15",c.uiOptions.times.to.max="23:45")}function $(){c.setRequestDateTimesAndDateTypes(),l(),L(),c.isCalculationUnit("hours")?k():c.request.toil_to_accrue=null}function E(){s.loadForm("/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1").on("crmUnload",function(){I(!1)})}function B(){c.showTOILAccrualsOptionEditorIcon=e.includes(["admin-dashboard","absence-tab"],o.section)}function U(){return f()?d().catch(a.resolve):a.resolve()}function F(){c.uiOptions.expiryDate&&(c.request.toil_expiry_date=c.convertDateToServerFormat(c.uiOptions.expiryDate))}t.debug("RequestModalDetailsToilController");var N,j=!c.isMode("create"),W={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};c.canDisplayToilExpirationField=!1,c.calculateBalanceChange=u,c.canCalculateChange=m,c.canSubmit=p,c.clearExpiryDate=h,c.initChildController=q,c.initTimesExtended=P,c.initWatchersExtended=R,c.onAbsenceTypeUpdateExtended=$,c.onDateChangeExtended=w,c.openToilInDaysAccrualOptionsEditor=E,c.resetUIInputsExtended=S,c.setDaysSelectionModeExtended=O,c.updateExpiryDate=F,function(){M(),x(),B(),!c.isMode("create")&&_()}()}t.controller("RequestModalDetailsToilController",a),a.$inject=["$log","$q","$rootScope","crmAngService","OptionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/absence-period.instance",["leave-absences/shared/modules/models-instances","common/moment","common/models/instances/instance","common/services/hr-settings"],function(e,n){"use strict";e.factory("AbsencePeriodInstance",["$log","ModelInstance","HR_settings",function(e,t,a){return e.debug("AbsencePeriodInstance"),t.extend({defaultCustomData:function(){return{current:!1}},transformAttributes:function(e){var t=n();return e.current=!1,n(e.start_date).isSameOrBefore(t,"day")&&n(e.end_date).isSameOrAfter(t,"day")&&(e.current=!0),e},isInPeriod:function(e){var t=a.DATE_FORMAT.toUpperCase(),o=n(e,t);return n(this.start_date).isSameOrBefore(o)&&n(this.end_date).isSameOrAfter(o)}})}])}),define("leave-absences/shared/apis/absence-period.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("AbsencePeriodAPI",["$log","api",function(e,n){return e.debug("AbsencePeriodAPI"),n.extend({all:function(n){return e.debug("AbsencePeriodAPI"),this.sendGET("AbsencePeriod","get",n).then(function(e){return e.values})}})}])}),define("leave-absences/shared/models/absence-period.model",["leave-absences/shared/modules/models","common/moment","leave-absences/shared/modules/shared-settings","leave-absences/shared/instances/absence-period.instance","leave-absences/shared/apis/absence-period.api","common/models/model","common/services/hr-settings"],function(e,n){"use strict";e.factory("AbsencePeriod",["$log","Model","AbsencePeriodAPI","AbsencePeriodInstance","shared-settings",function(e,t,a,o,s){return e.debug("AbsencePeriod"),t.extend({all:function(e){return a.all(e).then(function(e){return e.map(function(e){return o.init(e,!0)})})},current:function(){var e=n().format(s.serverDateFormat),t={start_date:{"<=":e},end_date:{">=":e}};return a.all(t).then(function(e){return e&&e.length?o.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,n){return e.debug("PublicHolidayAPI"),n.extend({all:function(n){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",n).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,n){return e.debug("PublicHolidayInstance"),n.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,n){"use strict";n.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(n,t,a,o,s){return n.debug("PublicHoliday"),t.extend({all:function(e){return n.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return o.init(e,!0)})})},isPublicHoliday:function(t){n.debug("PublicHoliday.isPublicHoliday",t);var o=e(t).format(s.serverDateFormat),i={date:o};return a.all(i).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,n){"use strict";n.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(n,t){return t.extend({defaultCustomData:function(){var n={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},t.defaultCustomData(),n)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(n){var t=this.getDocumentArray(),a=t.indexOf(n);e.contains(t,n)?t.splice(a,1):t.push(n),this.sickness_required_documents=t.join(",")},toAPIFilter:function(n,t,a){e.includes(["balance_change","dates","comments","files"],a)||(n[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,n){"use strict";n.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(n,t){return t.extend({defaultCustomData:function(){var n={from_date_amount:0,to_date_amount:0,request_type:"toil"};return e.assign({},t.defaultCustomData(),n)},toAPIFilter:function(n,t,a){e.includes(["balance_change","dates","comments","files"],a)||(n[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,n,t,a){"use strict";function o(n,o,s,i,r,c,u,l,d,m,f,p,h,v,b,g,_,y,q,C,T){function D(e){"days"===xe.selectedAbsenceType.calculation_unit_name?delete xe.request[e+"_date_amount"]:delete xe.request[e+"_date_type"]}function P(){["from","to"].forEach(D)}function A(){var e=xe.requestStatuses[y.statusNames.awaitingApproval].value;we.status_id===e&&e!==xe.request.status_id&&d.publish("ManagerBadge:: Update Count")}function R(){return Me.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function I(){return Me.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function w(){return!xe.loading.entitlements&&(!!se("admin")||!ae("view")&&!(se("manager")&&!ae("create")))}function O(){var e=R();return xe.isMode("edit")&&(e=e&&(G()||I())),xe.canManage&&xe.requestStatuses&&(e=e&&!!xe.getStatusFromValue(xe.newStatusOnSave)),(e=e&&!!xe.period.id)&&!xe.isMode("view")}function S(){xe.isSelfRecord?xe.request.status_id=xe.requestStatuses[y.statusNames.awaitingApproval].value:xe.canManage&&(xe.request.status_id=xe.newStatusOnSave||xe.request.status_id)}function k(){if(xe.isMode("edit")&&!xe.isRole("staff")&&"toil"!==N())return xe.request.calculateBalanceChange(xe.selectedAbsenceType.calculation_unit_name).then(function(e){if(+xe.balance.change.amount!=+e.amount)return T.promptBalanceChangeRecalculation().then(function(){s.$emit("LeaveRequestPopup::recalculateBalanceChange")}),o.reject()})}function L(){xe.errors=[]}function M(){return xe.request.create().then(Ce).then(function(){fe("LeaveRequest::new")})}function x(){ee()&&!xe.isRole("staff")&&(xe.request.change_balance=!0)}function $(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return xe.request.delete().then(function(){xe.dismissModal(),d.publish("LeaveRequest::delete",xe.request)})}})}function E(){r.dismiss({$value:"cancel"})}function B(){var e=N();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function U(){return F(xe.getStatusFromValue(xe.request.status_id).name)}function F(e){return t.map(Re[e],function(e){return xe.requestStatuses[e]})}function N(){return xe.request?xe.request.request_type:xe.leaveType||null}function j(){return!xe.request||e.equals({},xe.requestStatuses)?[]:xe.request.status_id?U():F("none")}function W(e){return t.find(xe.requestStatuses,function(n){return n.value===e})}function H(e){xe.errors=t.isArray(e)?e:[e],xe.loading.absenceTypes=!1,xe.submitting=!1}function G(){return!e.equals(we,xe.request.attributes())||xe.canManage&&xe.newStatusOnSave}function Y(){return xe.postContactSelection=!0,xe.staffMemberSelectionComplete=!1,xe.request.contact_id?o.resolve().then(re).then(ce).then(he).then(be).then(Z).then(z).then(xe.isMode("edit")?ge:t.noop).then(function(){xe.postContactSelection=!1,xe.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==ke)return o.reject(e)}):o.reject("The contact id was not set")}function V(){var e=[y.statusNames.moreInformationRequired,y.statusNames.approved,y.statusNames.rejected,y.statusNames.cancelled];Re.none=[y.statusNames.moreInformationRequired,y.statusNames.approved],Re.awaiting_approval=e,Re.more_information_required=e,Re.rejected=e,Re.approved=e,Re.cancelled=[y.statusNames.awaitingApproval].concat(e)}function z(){return xe.canManage?f.find(xe.request.contact_id).then(function(e){xe.contactName=e.display_name}):o.resolve()}function X(){Oe.push(s.$on("LeaveRequestPopup::requestObjectUpdated",ge),s.$on("LeaveRequestPopup::absencePeriodChanged",function(){ce().then(he).then(function(){s.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",xe.absenceTypes)})}),s.$on("LeaveRequestPopup::handleError",function(e,n){H(n)}),s.$on("LeaveRequestPopup::childComponent::register",function(){Ie++})),i.$on("$destroy",Te),i.$on("LeaveRequestPopup::addTab",function(e,n){Me.push(n)})}function Q(){var e,n;xe.request=xe.leaveRequest||null,e=N(),n=xe.initRequestAttributes(),"leave"===e?xe.request=_.init(n):"sickness"===e?xe.request=q.init(n):"toil"===e&&(xe.request=C.init(n))}function J(){var e={};return xe.request?e=xe.request.attributes():xe.canManage||(e={contact_id:Se}),e}function K(){if(Le="staff","my-leave"!==s.section)return c(y.permissions.admin.administer).then(function(e){e&&(Le="admin")}).then(function(){return"staff"===Le&&c(y.permissions.ssp.manage).then(function(e){e&&(Le="manager")})}).finally(function(){xe.canManage=xe.isRole("manager")||xe.isRole("admin")})}function Z(){(xe.isRole("admin")||xe.isMode("create")&&xe.isRole("manager"))&&(xe.newStatusOnSave=xe.requestStatuses[y.statusNames.approved].value)}function ee(){return!xe.request.status_id||!t.includes(["cancelled","rejected"],W(xe.request.status_id).name)}function ne(e){var n=xe.getStatusFromValue(xe.request.status_id);return!!n&&n.name===e}function te(e){return xe.request&&xe.request.request_type===e}function ae(e){return xe.mode===e}function oe(e,n){var t=a(e.from_date),o=a(e.to_date);return t.isSameOrAfter(n.start_date,"day")&&o.isSameOrBefore(n.end_date,"day")}function se(e){return Le===e}function ie(){return h.all().then(function(e){xe.absencePeriods=e})}function re(){return v.all(B()).then(v.loadCalculationUnits).then(function(e){Ae={types:e,ids:e.map(function(e){return e.id})}})}function ce(){return xe.loading.entitlements=!0,b.all({contact_id:xe.request.contact_id,period_id:xe.period.id,type_id:{IN:Ae.ids}},!0).finally(function(){xe.loading.entitlements=!1})}function ue(){return p.get().then(function(e){Se=e.contactId})}function le(){return xe.selectedContactId?f.find(xe.selectedContactId).then(function(e){xe.managedContacts=[e]}):xe.isRole("admin")?f.all().then(function(e){xe.managedContacts=t.remove(e.list,function(e){return e.id!==Se})}):f.find(Se).then(function(e){return e.leaveManagees()}).then(function(e){xe.managedContacts=e})}function de(){return u.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){xe.requestStatuses=t.indexBy(e,"name")})}function me(e,n){var a;return t.compact(e.map(function(e){if(a=t.find(n,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function fe(e){A(),d.publish(e,xe.request),xe.errors=[],xe.dismissModal()}function pe(){["from","to"].forEach(function(e){xe.request[e+"_date"]=we[e+"_date"]})}function he(e){if(xe.absenceTypes=me(Ae.types,e),!xe.absenceTypes.length)return o.reject(ke)}function ve(){xe.period=t.find(xe.absencePeriods,function(e){return xe.isMode("create")?e.current:oe(xe.request,e)})}function be(){xe.isMode("create")?(xe.selectedAbsenceType=xe.absenceTypes[0],xe.request.type_id=xe.selectedAbsenceType.id):xe.selectedAbsenceType=t.find(xe.absenceTypes,function(e){return e.id===xe.request.type_id})}function ge(){we=e.copy(xe.request.attributes())}function _e(){var e;xe.request.id?(e=[xe.requestStatuses[y.statusNames.approved].value,xe.requestStatuses[y.statusNames.adminApproved].value,xe.requestStatuses[y.statusNames.rejected].value,xe.requestStatuses[y.statusNames.cancelled].value],xe.mode="edit",xe.isRole("staff")&&e.indexOf(xe.request.status_id)>-1&&(xe.mode="view")):xe.mode="create"}function ye(){var e=xe.request.status_id;if(!xe.isMode("view")&&!xe.submitting)return xe.submitting=!0,S(),P(),xe.request.isValid().then(ee()&&k).then(x).then(!xe.request.change_balance&&pe).then(qe).then(function(){return xe.isMode("edit")?Pe():M()}).catch(function(n){xe.request.status_id=e,n&&H(n)}).finally(function(){xe.submitting=!1})}function qe(){return o.all(Me.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function Ce(){function e(e){e&&t.push(e),++a===Ie&&(t.length>0?n.reject(t):n.resolve())}var n=o.defer(),t=[],a=0;return Ie>0?s.$broadcast("LeaveRequestPopup::submit",e):n.resolve(),n.promise}function Te(){Oe.forEach(function(e){e()})}function De(){s.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function Pe(){return xe.request.update().then(Ce).then(function(){xe.isRole("manager")?fe("LeaveRequest::updatedByManager"):(xe.isRole("staff")||xe.isRole("admin"))&&fe("LeaveRequest::edit")})}n.debug("RequestCtrl");var Ae,Re={},Ie=0,we={},Oe=[],Se="",ke="No entitlement",Le="",Me=[],xe=t.assign(this,m);xe.absencePeriods=[],xe.absenceTypes=[],xe.canManage=!1,xe.contactName=null,xe.errors=[],xe.loading={absenceTypes:!0,entitlements:!0},xe.managedContacts=[],xe.mode="",xe.newStatusOnSave=null,xe.period={},xe.postContactSelection=!1,xe.requestStatuses={},xe.selectedAbsenceType={},xe.staffMemberSelectionComplete=!1,xe.submitting=!1,xe.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},xe.canChangeAbsenceType=w,xe.canSubmit=O,xe.closeAlert=L,xe.deleteLeaveRequest=$,xe.dismissModal=E,xe.getStatuses=j,xe.getStatusFromValue=W,xe.initAfterContactSelection=Y,xe.initRequestAttributes=J,xe.isLeaveStatus=ne,xe.isLeaveType=te,xe.isMode=ae,xe.isRole=se,xe.submit=ye,xe.updateAbsenceType=De,function(){xe.loading.absenceTypes=!0,V(),X(),o.all([ue(),K(),ie(),de()]).then(Q).then(_e).then(ve).then(function(){return xe.canManage&&!xe.isMode("edit")&&le()}).then(function(){if(xe.selectedContactId&&(xe.request.contact_id=xe.selectedContactId),xe.request.contact_id)return xe.initAfterContactSelection()}).catch(H).finally(function(){xe.loading.absenceTypes=!1})}()}n.controller("RequestCtrl",o),o.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,n){"use strict";function t(e,n,t,a,o,s,i,r,c){function u(e){return r.get().then(function(n){return e.roleOf(n.contactId)}).then(function(e){return"none"!==e})}function l(e,t,o,i,r){a.open({appendTo:n.children().eq(0),templateUrl:s.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:t,leaveRequest:e,selectedContactId:o,isSelfRecord:i,forceRecalculateBalanceChange:r}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return c.find(e).then(function(e){return u(e).then(function(n){n?l(e,e.request_type,e.contact_id,"my-leave"===t.section):o.error("Error","You dont have permission to see this leave request")})}).catch(function(e){o.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}n.factory("LeavePopup",t),t.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/absence-tab/modules/components",["common/angular"],function(e){return e.module("absence-tab.components",[])}),function(e){define("leave-absences/absence-tab/components/absence-tab-container.component",["leave-absences/absence-tab/modules/components"],function(n){function t(n,t,a){n.debug("Component: absence-tab-container"),t.section="absence-tab",this.contactId=e.adminId,function(){a.getDateFormat()}()}n.component("absenceTabContainer",{templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-container.html"}],controllerAs:"absence",controller:t}),t.$inject=["$log","$rootScope","DateFormat"]})}(CRM),define("leave-absences/absence-tab/components/absence-tab-entitlements.component",["common/lodash","leave-absences/absence-tab/modules/components"],function(e,n){function t(e,n,t){function a(){return t.all().then(t.loadCalculationUnits).then(function(e){o.absenceTypes=e})}n.debug("Component: absence-tab-entitlements");var o=this;o.absenceTypes=[],o.loading={component:!0},function(){a().finally(function(){o.loading.component=!1})}()}n.component("absenceTabEntitlements",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-entitlements.html"}],controllerAs:"entitlements",controller:t}),t.$inject=["$q","$log","AbsenceType"]}),define("leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component",["common/moment","leave-absences/absence-tab/modules/components"],function(e,n){function t(n,t,a,o,s,i,r){function c(e){m.errorMessage=e}function u(){return r.get({is_active:!0}).then(function(e){m.workPatterns=e})}function l(e){return s.valuesOf("hrleaveandabsences_work_pattern_change_reason",e).then(function(e){m.changeReasons=e})}function d(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_work_pattern_change_reason?reset=1").on("crmUnload",function(){l(!1)})}n.debug("Component: absence-tab-custom-work-pattern-modal");var m=Object.create(this);return m.changeReasons=[],m.errorMessage="",m.saveInProgress=!1,m.workPatterns=[],m.loading={content:!0},m.selected={workPattern:null,effectiveDate:null,changeReason:null},m.uiOptions={effectiveDate:{show:!1,options:{startingDay:1,showWeeks:!1}}},m.openWorkPatternChangeReasonEditor=d,function(){t.all([u(),l(!0)]).finally(function(){m.loading.content=!1})}(),m.closeModal=function(){m.dismiss({$value:"cancel"})},m.closeAlert=function(){m.errorMessage=""},m.save=function(){var n=e(m.selected.effectiveDate).format(i.serverDateFormat);return m.saveInProgress=!0,r.assignWorkPattern(m.contactId,m.selected.workPattern.id,n,null,m.selected.changeReason).then(function(){a.$broadcast("CustomWorkPattern::Added"),m.closeModal()}).catch(c).finally(function(){m.saveInProgress=!1})},m}n.component("absenceTabCustomWorkPatternModal",{bindings:{contactId:"<",dismiss:"&"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-custom-work-pattern-modal.html"}],controllerAs:"workPatternModal",controller:["$log","$q","$rootScope","crmAngService","OptionGroup","shared-settings","WorkPatternAPI",t]})}), +define("leave-absences/absence-tab/components/absence-tab-work-patterns.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component"],function(e,n,t){function a(t,a,o,s,i,r,c,u,l,d){function m(){return d.workPatternsOf(g.contactId,{},!1).then(function(e){g.customWorkPatterns=e})}function f(){return d.default().then(function(e){g.defaultWorkPattern=e})}function p(){return l.valuesOf("hrleaveandabsences_work_pattern_change_reason").then(function(n){b=e.indexBy(n,"value")})}function h(e){var n=[m()];return e&&(n=n.concat(e)),g.loading.workPattern=!0,a.all(n).then(function(){v()}).finally(function(){g.loading.workPattern=!1})}function v(){var t,a=u.DATE_FORMAT.toUpperCase();g.customWorkPatterns=e(g.customWorkPatterns).map(function(e){return t=b[e.change_reason],e.change_reason_label=t?t.label:"",e.effective_date=e.effective_date?n(e.effective_date).format(a):"",e}).sortBy(function(e){return-n(e.effective_date,a).valueOf()}).value()}t.debug("Component: absence-tab-work-patterns");var b=[],g=Object.create(this);return g.customWorkPatterns=[],g.defaultWorkPattern=null,g.linkToWorkPatternListingPage=function(){var e=CRM.url("civicrm/contact/view",{cid:g.contactId,selectedChild:"absence"});return CRM.url("civicrm/admin/leaveandabsences/work_patterns",{cid:g.contactId,returnUrl:e})}(),g.loading={workPattern:!0},function(){h([p(),f(),c.getDateFormat()]),s.$on("CustomWorkPattern::Added",function(){h()})}(),g.deleteWorkPattern=function(e){r.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){d.unassignWorkPattern(e).then(function(){h()})}})},g.openModal=function(){i.open({appendTo:o.children().eq(0),template:'',controller:["$uibModalInstance",function(e){this.dismiss=e.dismiss}],controllerAs:"$ctrl"})},g}t.component("absenceTabWorkPatterns",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/absence-tab-work-patterns.html"}],controllerAs:"workpatterns",controller:["$log","$q","$rootElement","$rootScope","$uibModal","dialog","DateFormat","HR_settings","OptionGroup","WorkPattern",a]})}),define("leave-absences/absence-tab/components/annual-entitlement-change-log.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contract"],function(e,n,t){function a(t,a,o,s,i){function r(){return l().then(function(e){q=q.concat(e)})}function c(){var n=e.groupBy(q,"created_date");C.changeLogRows=e.map(n,d).sort(function(e,n){return n.date.diff(e.date)})}function u(e,n){var t,a,o=m(e);e.entitlements.forEach(function(s,i){t=o.entitlements.slice(0,i),a=e.entitlements.slice(i+1),n(s,t,a)})}function l(){return o.all({contact_id:C.contactId,period_id:C.periodId},!1).then(function(e){return e.map(function(e){return{comment:e.comment,contact_id:e.contact_id,created_date:e.created_date,editor_id:e.editor_id,entitlement_amount:e.value,entitlement_id:e.id,"entitlement_id.type_id":e.type_id}})})}function d(t,a){var o,s,i;return s=e.indexBy(t,"entitlement_id.type_id"),i=C.absenceTypes.map(function(n){return o=s[n.id],e.extend({calculation_unit:n.calculation_unit_name},o)}),{date:n(a),entitlements:i}}function m(e){var n;return n=C.changeLogRows.indexOf(e),C.changeLogRows[n+1]||{date:e.date.clone(),entitlements:e.entitlements.map(function(){return{}})}}function f(){for(var n,t,a,o=C.changeLogRows.length-1;o>=0;o--)if(n=C.changeLogRows[o],t=e.pluck(n.entitlements,"comment"),a=e.compact(t),1===a.length){var s=e.findIndex(t,"length");n.highlightedEntitlement=n.entitlements[s]}else a.length>1&&_(o)}function p(e,n){C.changeLogRows.splice(n,0,e)}function h(){return t.all({id:C.periodId}).then(function(e){C.absencePeriod=e[0]})}function v(e){return a.all().then(a.loadCalculationUnits).then(function(e){C.absenceTypes=e})}function b(){return o.logs({contact_id:C.contactId,period_id:C.periodId}).then(function(e){q=e})}function g(){var e,n;if(!(C.changeLogRows.length<=1))for(e=C.changeLogRows.length-2,n=C.changeLogRows.length-1;e>=0;){var t=C.changeLogRows[e],a=C.changeLogRows[n];t.entitlements.forEach(function(e,n){var t=a.entitlements[n];e.comment===t.comment&&delete e.comment}),e--,n--}}function _(e){var n,t,a=C.changeLogRows[e];u(a,function(o,s,i){o.comment&&(n=s.concat(o).concat(i),t={date:a.date.clone(),entitlements:n},t.highlightedEntitlement=o,p(t,e++))}),y(e)}function y(e){C.changeLogRows.splice(e,1)}var q=[],C=this;C.absencePeriod=null,C.absenceTypes=[],C.changeLogRows=[],C.loading={component:!0},function(){h().then(v).then(b).then(r).then(c).then(g).then(f).finally(function(){C.loading.component=!1})}()}t.component("annualEntitlementChangeLog",{bindings:{contactId:"<",periodId:"<",dismissModal:"&"},templateUrl:["settings",function(e){return e.pathTpl+"components/annual-entitlement-change-log.html"}],controllerAs:"changeLog",controller:a}),a.$inject=["AbsencePeriod","AbsenceType","Entitlement","OptionGroup","shared-settings"]}),function(e){define("leave-absences/absence-tab/components/annual-entitlements.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contact"],function(n,t,a){function o(a,o,s,i,r,c,u,l,d){function m(){T.absencePeriods=n.chain(T.absencePeriods).filter(function(e){return n.find(q,function(n){return n.period_id===e.id})}).sortBy(function(e){return-t(e.start_date).valueOf()}).value()}function f(){T.absenceTypes=n.filter(T.absenceTypes,function(e){return n.find(q,function(n){return n.type_id===e.id})})}function p(n){var t=e.url("civicrm/contact/view",{cid:T.contactId,selectedChild:"absence"});return e.url("civicrm/admin/leaveandabsences/periods/manage_entitlements",{id:n,cid:T.contactId,returnUrl:t})}function h(){return c.all().then(function(e){T.absencePeriods=e})}function v(){var e=n.uniq(n.map(q,function(e){return e.editor_id}));return l.all({id:{IN:e}}).then(function(e){C=n.indexBy(e.list,"contact_id")})}function b(){return u.all({contact_id:T.contactId}).then(function(e){q=e})}function g(e){i.open({appendTo:s.children().eq(0),templateUrl:"annual-entitlement-change-log-modal",controller:["$uibModalInstance",function(n){this.contactId=T.contactId,this.dismiss=n.dismiss,this.periodId=e}],controllerAs:"modal"})}function _(){T.absencePeriods=n.map(T.absencePeriods,function(e){var t=n.map(T.absenceTypes,function(t){var a=n.find(q,function(n){return n.type_id===t.id&&n.period_id===e.id});return a?{amount:a.value,calculation_unit:t.calculation_unit_name,comment:a.comment?{message:a.comment,author_name:C[a.editor_id].display_name,date:a.created_date}:null}:null});return{id:e.id,title:e.title,entitlements:t}})}function y(e){var n=e.message+"

    Last updated:
    By: "+e.author_name+"
    Date: "+t.utc(e.date).local().format("DD/M/YYYY HH:mm")+"
    ";d.info("Calculation comment:",n)}a.debug("Component: annual-entitlements");var q=[],C=[],T=this;T.absencePeriods=[],T.loading={absencePeriods:!0},T.getEditEntitlementsPageURL=p,T.openAnnualEntitlementChangeLog=g,T.showComment=y,function(){b().then(v).then(h).then(m).then(f).then(_).finally(function(){T.loading.absencePeriods=!1})}()}a.component("annualEntitlements",{bindings:{absenceTypes:"<",contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/annual-entitlements.html"}],controllerAs:"entitlements",controller:o}),o.$inject=["$log","$q","$rootElement","$uibModal","AbsenceType","AbsencePeriod","Entitlement","Contact","notificationService"]})}(CRM),define("leave-absences/absence-tab/components/contract-entitlements.component",["common/lodash","common/moment","leave-absences/absence-tab/modules/components","common/models/contract"],function(e,n,t){function a(t,a,o,s,i,r){function c(){m.absenceTypes=e.filter(m.absenceTypes,function(n){return e.find(m.contracts,function(t){return e.find(t.info.leave,function(e){return e.leave_type===n.id})})})}function u(e){var t=o.DATE_FORMAT.toUpperCase();return e?n(e).format(t):""}function l(){return i.all({contact_id:m.contactId}).then(function(e){m.contracts=e})}function d(){m.contracts=e.sortBy(m.contracts,function(e){return n(e.info.details.period_start_date)}).map(function(n){var t=n.info,a=t.details,o=e.map(m.absenceTypes,function(n){var a=e.filter(t.leave,function(e){return e.leave_type===n.id})[0];return{amount:a?a.leave_amount:"",calculation_unit:n.calculation_unit_name}});return{position:a.position,start_date:u(a.period_start_date),end_date:u(a.period_end_date),absences:o}})}t.debug("Component: contract-entitlements");var m=this;m.contracts=[],m.loading={contracts:!0},function(){r.getDateFormat().then(l).then(c).then(d).finally(function(){m.loading.contracts=!1})}()}t.component("contractEntitlements",{bindings:{absenceTypes:"<",contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/contract-entitlements.html"}],controllerAs:"entitlements",controller:a}),a.$inject=["$log","$q","HR_settings","AbsenceType","Contract","DateFormat"]}),function(e){define("leave-absences/absence-tab/modules/settings",["common/angular"],function(n){return n.module("absence-tab.settings",[]).constant("settings",{contactId:e.vars.leaveAndAbsences.contactId,debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/absence-tab/"})})}(CRM),define("leave-absences/absence-tab/modules/config",["common/angular","leave-absences/absence-tab/modules/settings"],function(e){return e.module("absence-tab.config",["absence-tab.settings"]).config(["$resourceProvider","$httpProvider","$logProvider","settings",function(e,n,t,a){t.debugEnabled(a.debug),e.defaults.stripTrailingSlashes=!1,n.defaults.headers.common["X-Requested-With"]="XMLHttpRequest"}])}),define("leave-absences/absence-tab/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/modules/directives","common/services/check-permissions","common/services/crm-ang.service","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/modules/shared-settings","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/work-pattern.model","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/staff-leave-report.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/work-pattern.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/absence-tab/components/absence-tab-container.component","leave-absences/absence-tab/components/absence-tab-entitlements.component","leave-absences/absence-tab/components/absence-tab-work-patterns.component","leave-absences/absence-tab/components/annual-entitlement-change-log.component","leave-absences/absence-tab/components/annual-entitlements.component","leave-absences/absence-tab/components/contract-entitlements.component","leave-absences/absence-tab/modules/config"],function(e){return e.module("absence-tab",["ngResource","ui.bootstrap","textAngular","common.angularDate","common.dialog","common.directives","common.filters","common.services","common.mocks","leave-absences.settings","leave-absences.models","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","leave-absences.settings","absence-tab.config","absence-tab.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,n,t,a){e.debug("app.run"),n.sharedPathTpl=t.sharedPathTpl,n.settings=a}]),e}),function(e,n){var t=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";n.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":t+"/shared","leave-absences/absence-tab":t+"/absence-tab"}}),n(["leave-absences/shared/config"],function(){n(["leave-absences/absence-tab/app"],function(){document.dispatchEvent("function"==typeof window.CustomEvent?new CustomEvent("absenceTabReady"):function(){var e=document.createEvent("Event");return e.initEvent("absenceTabReady",!0,!0),e}())})})}(CRM,require),define("absence-tab",function(){}); //# sourceMappingURL=/sites/all/modules/civicrm/tools/extensions/civihr/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/absence-tab.js.map \ No newline at end of file diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/admin-dashboard.min.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/admin-dashboard.min.js index 819333dc536..989685bc2ee 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/admin-dashboard.min.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/admin-dashboard.min.js @@ -6,9 +6,9 @@ */ -!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return W(new(W(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[f]),c[r[f]]=e[r[f]]);return W({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))v.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&m(u[e],e)}),v.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var h=s(u||{}),v=[],g=[],b={};return H(u,m),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),m.$$values=b,m.$$promises=m.$$promises||!0,delete m.$$inheritedValues,c.resolve(b))}function u(e){m.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),m=c.promise,g=m.$$promises={},b=W({},a),y=1+v.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),m;o.$$inheritedValues&&r(b,f(o.$$inheritedValues,h)),W(g,o.$$promises),o.$$values?(_=r(b,f(o.$$values,h)),m.$$inheritedValues=f(o.$$values,h),i()):(o.$$inheritedValues&&(m.$$inheritedValues=f(o.$$inheritedValues,h)),o.then(i,u));for(var q=0,$=v.length;q<$;q+=3)a.hasOwnProperty(v[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(m.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),f=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(f++,g[e].then(function(t){b[e]=t,--f||l()},c))}),f||l(),g[n]=d.promise}(v[q],v[q+1],v[q+2]);return m}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(v.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(h[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return h[t]=new Y.Param(t,n,a,r),h[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(f,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=W({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",f=0,m=this.segments=[],p=r?r.params:{},h=this.params=r?r.params.$$new():new Y.ParamSet,v=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),m.push(g.segment),f=c.lastIndex;y=e.substring(f);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,f+_),q.length>0)for(f=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),f=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",m.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=m[0],this.$$paramNames=v}function y(e){W(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:h,caseInsensitive:f}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){W(this,e||{})}Y=this;var d,f=!1,h=!0,v=!1,g={},q=!0,$=[],C={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(f=e),f},this.strictMode=function(e){return j(e)&&(h=e),h},this.defaultSquashPolicy=function(e){if(!j(e))return v;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return v=e,e},this.compile=function(e,t){return new b(e,W(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(W({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(C,function(e,t){g[t]=new y(W({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(C,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!h.type.is(e))throw new Error("Default value ("+e+") for parameter '"+h.id+"' is not an instance of Type ("+h.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(m(h.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?h.type.$normalize(e):c()}function f(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var h=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return W(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return v;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),m(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);W(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:f})},l.prototype={$$new:function(){return a(this,W(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return m(r,t.self);for(var o in S)B(S[o])&&(t[o]=S[o](t,S.$delegates[o]));return P[n]=t,!t[R]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){A.$current.navigable==t&&c(e,n)||A.transitionTo(t,e,{inherit:!0,location:!1})}]),v(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=A.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=M[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.$current=t,A.current=t.self,A.params=n,V(A.params,m),A.transition=null,o.location&&t.navigable&&v.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),v.update(!0),A.current)}).then(null,function(a){return a===D?S:A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||v.update(),r.reject(a))});return B},A.is=function(e,t,a){a=W({relative:A.$current},a||{});var r=f(e,a.relative);return j(r)?A.$current===r&&(!t||c(r.params.$$values(t),m)):n},A.includes=function(e,t,a){if(a=W({relative:A.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=A.$current.name}var r=f(e,a.relative);if(!j(r))return n;if(!j(A.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(f&&(f.remove(),f=null),p&&(p.$destroy(),p=null),m){var e=m.data("$uiViewAnim");b.leave(m,function(){e.$$animLeave.resolve(),f=null}),f=m,m=null}}function d(s){var d,f=D(n,c,i,r),y=f&&e.$current&&e.$current.locals[f];if(s||y!==h){d=n.$new(),h=e.$current.locals[f],d.$emit("$viewContentLoading",f);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});m=_,p=d,p.$emit("$viewContentLoaded",f),p.$eval(v)}}var f,m,p,h,v=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=D(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var f=t.extend({},d);o[d.$$resolveAs]=f;var m=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=f),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}m(o)}}}}}function D(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function R(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function S(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function T(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function I(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function O(e,t){return{relative:S(e)||t.$current,inherit:!0}}function L(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=R(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=T(r),d=s[1]||s[0],f=null;c.options=W(O(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var m=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),f&&f(),d&&(f=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&m(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),m(),l.clickable&&(i=I(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function M(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){f.state=t[0],f.params=t[1],f.options=t[2],f.href=e.href(f.state,f.params,f.options),m&&m(),c&&(m=c.$$addStateInfo(f.state,f.params)),f.href&&r.$set(u.attr,f.href)}var i,u=T(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",f={state:null,params:null,options:null,href:null},m=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=I(a,e,t,u,function(){return f}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function k(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,S(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return h.push(u),v[s]=r,function(){var e=h.indexOf(u);-1!==e&&h.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function x(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function E(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,W=t.extend,V=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),v.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",v),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,W(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;aWhen All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,f){function m(){for(var e=[],t=n(M.selectedPeriod.start_date).clone().startOf("month"),a=n(M.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");M.months=e}function p(){s.$new().$watch(function(){return M.selectedMonths},function(t,n){null===n||e.equals(t,n)||R()})}function h(e){M.injectMonths=!0,I("injected").then(function(){R(e)}).then(function(){M.loading.calendar=!1})}function v(){O=a("LeaveCalendar"+t.capitalize(L)+"Controller").init(M)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){M.absencePeriods=t.sortBy(e,"start_date"),M.selectedPeriod=t.find(M.absencePeriods,function(e){return!!e.current})}).then(m).then(S)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return O.loadContacts().then(function(e){M.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){M.filters.optionValues.regions=e.hrjc_region,M.filters.optionValues.locations=e.hrjc_location,M.filters.optionValues.levelTypes=e.hrjc_level_type,M.filters.optionValues.departments=e.hrjc_department})}function C(){return l.all()}function w(){return r.all([y(),C(),_()]).then(function(e){M.supportData.absenceTypes=e[0],M.supportData.publicHolidays=e[1],M.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,M.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,M.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,M.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function A(){var e=r.resolve();return M.injectMonths&&(e=I("destroyed"),M.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function D(e){e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){M.loading.calendar=!0}).then(A).then("period"===e?m:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function R(e){var n=M.selectedMonths.length?M.months.filter(function(e){return t.includes(M.selectedMonths,e.index)}):M.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function S(){M.selectedMonths=[n().month()]}function T(){return M.roleOverride?r.resolve().then(function(){L=M.roleOverride}):r.all([f(i.permissions.admin.administer),f(i.permissions.ssp.manage)]).then(function(e){L=e[0]?"admin":e[1]?"manager":"staff"})}function I(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===M.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var O,L,M=this;M.absencePeriods=[],M.contacts=[],M.contactIdsToReduceTo=null,M.injectMonths=!1,M.months=[],M.selectedMonths=null,M.selectedPeriod=null,M.showContactName=!1,M.showFilters=!1,M.supportData={},M.loading={calendar:!0,page:!0},M.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},M.labelPeriod=g,M.refresh=D,function(){T().then(p).then(v).then(A).then(b).then(function(){return r.all([q(),w()])}).then(function(){return M.showFilters?$():t.noop}).then(function(){h()}).then(function(){M.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r){"use strict";function o(){_.calculationUnit=s(_.supportData.calculationUnits,"value",g.calculation_unit)}function s(t,n,a){return e.find(t,function(e){return+e[n]==+a})}function i(){var e,n;return n=t(_.contactData.leaveRequest.from_date).isSame(_.contactData.leaveRequest.to_date,"day"),e=n?"single-date":"multiple-dates","type-"+_.calculationUnit.name+"-on-"+e+"-tooltip"}function u(){g=s(_.supportData.absenceTypes,"id",_.contactData.leaveRequest.type_id),_.contactData.leaveRequest["type_id.title"]=g.title}function c(){"days"===_.calculationUnit.name&&(b=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.from_date_type),y=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.to_date_type),_.contactData.leaveRequest["from_date_type.label"]=b.label,_.contactData.leaveRequest["to_date_type.label"]=y.label)}function l(e,t,n,a,o){e.stopPropagation(),r.openModal(t,n,a,o)}function d(){_.dates.from=new Date(_.contactData.leaveRequest.from_date),_.dates.to=new Date(_.contactData.leaveRequest.to_date)}function f(){_.contactData.isAccruedTOIL?_.label="AT":"days"===_.calculationUnit.name?m():p()}function m(){_.label=_.contactData.isAM?"AM":_.contactData.isPM?"PM":""}function p(){var e=t(_.contactData.leaveRequest.from_date).isSame(_.date,"day"),n=t(_.contactData.leaveRequest.to_date).isSame(_.date,"day");_.label=e?t(_.contactData.leaveRequest.from_date).format("HH:mm"):n?t(_.contactData.leaveRequest.to_date).format("HH:mm"):""}function h(){_.tooltipTemplate=_.contactData.isAccruedTOIL?"accrued-toil-tooltip":i()}function v(){a.$watch("day.contactData.leaveRequest",function(){_.contactData&&_.contactData.leaveRequest&&(u(),o(),c(),f(),d(),h())})}n.debug("Component: leave-calendar-day");var g,b,y,_=this;_.calculationUnit="",_.dates={from:null,to:null},_.label="",_.tooltipTemplate=null,_.openLeavePopup=l,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){y([e]),B(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(W.period.start_date)&&r.isSameOrBefore(W.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function f(e){return U[e]}function m(){return W.showOnlyWithLeaveRequests?W.contacts.filter(function(e){return Object.keys(H[e.id]||{}).length}):W.contacts}function p(e){return t(e,u.serverDateFormat)}function h(e){O(e),B(e)}function v(e){return CRM.url("civicrm/contact/view",{cid:e})}function g(){return W.contactIdsToReduceTo&&(W.contacts=W.contacts.filter(function(t){return e.includes(W.contactIdsToReduceTo,t.contact_id)||e.find(H,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function b(){W.supportData.dayTypes=e.indexBy(W.supportData.dayTypes,"name"),W.supportData.leaveRequestStatuses=e.indexBy(W.supportData.leaveRequestStatuses,"value"),W.supportData.publicHolidays=e.transform(W.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function y(e){return e.forEach(function(e){var t=A(e);H[e.contact_id]=H[e.contact_id]||{},t.forEach(function(t){H[e.contact_id][t.date]=e})}),a.resolve()}function _(){F.push(r.$on("LeaveCalendar::showMonths",x)),F.push(i.subscribe("LeaveRequest::new",c)),F.push(i.subscribe("LeaveRequest::edit",j)),F.push(i.subscribe("LeaveRequest::updatedByManager",j)),F.push(i.subscribe("LeaveRequest::delete",h)),F.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):j(e.leaveRequest)}))}function q(e,n,a){var r=W.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function $(e,t){return e.request_type===t}function C(e){return!!W.supportData.publicHolidays[p(e).valueOf()]}function w(t){var n=W.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function A(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===W.month.index&&r.year()===W.month.year&&a.push(e.find(W.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function P(t){return e.find(H[t.contact_id],function(e){return t.id===e.id})}function D(t){var n=e.find(W.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function R(){return[D(u.statusNames.approved),D(u.statusNames.adminApproved),D(u.statusNames.awaitingApproval),D(u.statusNames.moreInformationRequired)]}function S(){return W.month.loading=!0,a.all([I(),T()]).then(g).then(k).then(function(){N=!0}).then(function(){W.month.loading=!1})}function T(){return s.all({from_date:{to:W.month.days[W.month.days.length-1].date},to_date:{from:W.month.days[0].date},status_id:{IN:R()},contact_id:{IN:W.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(W.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return y(e.list)})}function I(){var t=W.month.days[0].date,n=W.month.days[W.month.days.length-1].date;return o.get(W.contacts.map(function(e){return e.id}),t,n).then(function(t){U=e.indexBy(t,"contact_id")})}function O(t){H[t.contact_id]=e.omit(H[t.contact_id],function(e){return e.id===t.id})}function L(){r.$emit("LeaveCalendar::monthDestroyed"),F.map(function(e){e.remove?e.remove():e()})}function M(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=f(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:C(t.date)})}),o.then(function(){return H[n]?H[n][t.date]:null}).then(function(a){e.assign(t.contactsData[n],{leaveRequest:a||null,styles:a?E(a):null,isAccruedTOIL:a?$(a,"toil"):null,isRequested:a?w(a):null,isAM:a?q("half_day_am",a,t.date):null,isPM:a?q("half_day_pm",a,t.date):null})})}function k(){return a.all(W.month.days.map(function(e){return a.all(W.contacts.map(function(t){return M(e,t.id)}))}))}function x(t,n,a){!e.find(n,function(e){return e.index===W.month.index})?W.visible=!1:(W.currentPage=0,W.visible=!0,(a||!N)&&S())}function E(t){var n=e.find(W.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function j(e){var t=P(e);t&&(h(t),-1!==R().indexOf(e.status_id)&&c(e))}function B(e){return a.all(A(e).map(function(t){return M(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var N=!1,F=[],U={},H={},W=this;W.currentPage=0,W.pageSize=20,W.visible=!1,W.showContactName=!!W.showContactName,W.showOnlyWithLeaveRequests=!!W.showOnlyWithLeaveRequests,W.$onDestroy=L,W.contactsList=m,W.getContactUrl=v,function(){var e=t().month(W.month.index).year(W.month.year);b(),_(),W.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o,promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(h(t)):m(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function f(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||!!e.includes([$.awaitingApproval,$.moreInformationRequired],n)&&("manager"===q.role||("3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a))}function m(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=C[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function v(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(C,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!f(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:C[e].label,isDirectAction:C[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,C={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}), -define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function f(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function m(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=f,q.getActiveComments=m,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f,m){function p(){pe.balance.closing=pe.balance.opening+pe.balance.change.amount}function h(e){return t(e,u.serverDateFormat).toDate()}function v(e){return t(e).format(u.serverDateFormat)}function g(e){var t;return s.resolve().then(function(){X(e),"from"===e&&K(),B("hours")&&(_(e),"from"!==e||pe.uiOptions.multipleDays||_("to")),pe.loading[e+"DayTypes"]=!0}).then(pe.onDateChangeExtended).then(function(){return C(e)}).then(function(e){if(t=e.id!==pe.period.id,t&&(pe.period=e),!pe.period.id)return s.reject("Please change date as it is not in any absence period")}).then(Z).then(function(){if(t)return V()}).then(function(){return U(pe.uiOptions[e+"Date"],e)}).then(function(){if(B("hours"))return W(e).then(function(){ne(e,!0)})}).then(function(){if(oe(),!t)return Y();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(S)}function b(){return oe(),Y()}function y(){return pe.uiOptions.toDate=null,X("to"),s.resolve().then(function(){if(B("hours")&&pe.uiOptions.fromDate)return _("from"),!pe.uiOptions.multipleDays&&_("to"),W("from").then(function(){ne("from",!0)}).then(oe)}).then(pe.setDaysSelectionModeExtended).then(!pe.uiOptions.multipleDays&&Y)}function _(e){var t=pe.uiOptions.times[e];t.loading=!0,t.disabled=!0}function q(t,n){var a=pe.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);pe.uiOptions.multipleDays||("from"===t&&o&&r&&(o=P(o).subtract(pe.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=P(r).add(pe.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min,a.disabled=!1}function $(t,n){return t?(t=v(t),d.isPublicHoliday(t).then(function(n){return n?pe.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):w(t,pe.requestDayTypes).then(function(t){return t.length?t:pe.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return te(n,e),e})):s.reject([])}function C(n){var a=t(pe.uiOptions[n+"Date"]).format(pe.uiOptions.userDateFormat.toUpperCase());return e.find(pe.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function w(e,n){return e=t(e),s.all([pe.calendar.isNonWorkingDay(e),pe.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function A(){return pe.request?pe.request.request_type:pe.leaveType||null}function P(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function D(){return ie(),pe.loading.balanceChange=!0,pe.request.getBalanceChangeBreakdown().then(Q).catch(S)}function R(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function S(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),pe.loading.fromDayTypes=!1,pe.loading.balanceChange=!1,pe.loading.tab=!1,pe.loading.toDayTypes=!1}function T(){return pe.isMode("create")||pe.forceRecalculateBalanceChange?Y():D()}function I(){var e=pe.request.attributes();return pe.uiOptions.fromDate=h(pe.request.from_date),U(pe.uiOptions.fromDate,"from").then(function(){return pe.request.to_date=e.to_date,pe.request.to_date_type=e.to_date_type,pe.uiOptions.toDate=h(pe.request.to_date),U(pe.uiOptions.toDate,"to")})}function O(e){o.$watch("detailsTab.uiOptions.times."+e+".amount",function(e,t){B("days")||+e==+t||(se(),pe.performBalanceChangeCalculation())})}function L(){me.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){ce()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){le(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",Y))}function M(){pe.isMode("edit")&&(pe.isLeaveStatus(u.statusNames.approved)||pe.isLeaveStatus(u.statusNames.adminApproved))&&(fe={absenceTypeId:pe.request.type_id,value:pe.selectedAbsenceType.remainder-pe.request.balance_change})}function k(e){var n=t(pe.request[e+"_date"]).format("HH:mm"),a=pe.uiOptions.times[e];(R(a.min,n)<=0||R(a.max,n)>=0)&&(n="from"===e?a.min:a.max),pe.uiOptions.times[e].time=n}function x(){var e=pe.uiOptions.multipleDays?["from","to"]:["from"],t=pe.uiOptions.times;return s.all(e.map(W)).then(function(){["from","to"].forEach(function(e){k(e),ne(e),t[e].amount=Math.min(pe.request[e+"_date_amount"],t[e].maxAmount).toString()}),pe.uiOptions.multipleDays||de(pe.uiOptions.times.from.time)}).then(se)}function E(){["from","to"].forEach(function(e){O(e),j(e)})}function j(e){o.$watch("detailsTab.uiOptions.times."+e+".time",function(t,n){B("days")||t===n||(oe(),t&&(!pe.uiOptions.multipleDays&&"from"===e&&de(t),ne(e,!0)))})}function B(e){return pe.selectedAbsenceType.calculation_unit_name===e}function N(e){return pe.request.request_type===e}function F(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function U(e,t){return $(e,t).then(function(){pe.loading[t+"DayTypes"]=!1})}function H(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){pe.requestDayTypes=e})}function W(e){var t=pe.uiOptions[e+"Date"],n=pe.uiOptions.times[e],a=!pe.uiOptions.multipleDays;return t?pe.request.getWorkDayForDate(v(t)).then(function(t){he[e]=t,q(e,t),a&&"from"===e&&q("to",t)}).catch(function(t){return he[e]={},S(t)}).finally(function(){n.loading=!1,a&&(pe.uiOptions.times.to.loading=!1)}):s.resolve()}function V(){return c.get(pe.request.contact_id,pe.period.start_date,pe.period.end_date).then(function(e){pe.calendar=e})}function G(){var e=(pe.pagination.currentPage-1)*pe.pagination.numPerPage,t=e+pe.pagination.numPerPage;pe.pagination.filteredbreakdown=pe.balance.change.breakdown.slice(e,t)}function Y(){return ie(),pe.canCalculateChange()?(pe.loading.balanceChange=!0,pe.request.change_balance=!0,pe.calculateBalanceChange().then(Q).catch(S).finally(function(){pe.loading.balanceChange=!1})):s.resolve()}function z(){pe.pagination.totalItems=pe.balance.change.breakdown.length,pe.pagination.filteredbreakdown=pe.balance.change.breakdown,pe.pagination.pageChanged()}function J(){return v(pe.request.from_date)===v(pe.request.to_date)}function K(){pe.uiOptions.toDate&&pe.uiOptions.fromDate&&pe.uiOptions.multipleDays&&t(pe.uiOptions.toDate).isSameOrBefore(pe.uiOptions.fromDate)&&(pe.uiOptions.toDate=null,X("to"))}function X(t){var n=pe.uiOptions.times[t];pe["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0",n.loading=!1,oe(),se(),ie()}function Q(e){pe.balance.change=e,pe.request.balance_change=e.amount,p(),z(),pe.loading.balanceChange=!1}function Z(){var e,n,a;pe.uiOptions.fromDate?(e=t(pe.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=h(pe.period.start_date),n=pe.uiOptions.date.to.options.minDate),pe.uiOptions.date.to.options.initDate=n,pe.uiOptions.date.to.options.minDate=a,pe.uiOptions.date.to.options.maxDate=h(pe.period.end_date)}function ee(){return!pe.isMode("create")&&J()||pe.isMode("create")&&(N("sickness")||B("hours"))?pe.uiOptions.multipleDays=!1:pe.uiOptions.multipleDays=!0,s.resolve().then(pe.setDaysSelectionModeExtended)}function te(t,n){var a="request"+e.startCase(t)+"DayTypes";pe[a]=n,pe.isMode("create")&&(pe.request[t+"_date_type"]=pe[a][0].value)}function ne(e,t){var n=pe.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,s=n.multipleDays&&"from"===a?r.max:n.times.to.time,i=he[a].number_of_hours?R(o,s).toString():"0";r.maxAmount=i,t&&(r.amount=r.maxAmount)}function ae(){fe&&fe.absenceTypeId===pe.selectedAbsenceType.id?pe.balance.opening=fe.value||0:pe.balance.opening=pe.selectedAbsenceType.remainder}function re(){pe.selectedAbsenceType=e.find(pe.absenceTypes,function(e){return e.id===pe.request.type_id})}function oe(){var e=pe.uiOptions,t=e.times;pe.request.from_date=e.fromDate?v(e.fromDate):null,pe.request.to_date=e.toDate?v(e.toDate):null,!e.multipleDays&&e.fromDate&&(pe.request.to_date=pe.request.from_date,pe.request.to_date_type=pe.request.from_date_type),B("hours")&&!N("toil")&&(pe.request.from_date=pe.request.from_date&&t.from.time?pe.request.from_date+" "+t.from.time:null,pe.request.to_date=pe.request.to_date&&t.to.time?pe.request.to_date+" "+t.to.time:null)}function se(){var e=pe.uiOptions.times;pe.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,pe.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function ie(){pe.uiOptions.showBalance=pe.canCalculateChange()}function ue(){e.forEach(me,function(e){e()})}function ce(){var e,t=pe.selectedAbsenceType.calculation_unit_name;return re(),e=t!==pe.selectedAbsenceType.calculation_unit_name,ae(),s.resolve().then(e&&ee).then(function(){if(e&&B("hours"))return W("from").then(function(){ne("from",!0)})}).then(e&&oe).then(Y)}function le(e){return pe.absenceTypes=e,re(),t(pe.uiOptions.toDate).isAfter(pe.period.end_date)&&(pe.uiOptions.toDate=void 0,X("to")),ae(),Y()}function de(e){var t=P(e).add(pe.uiOptions.time_interval,"minutes");t.isAfter(P(pe.uiOptions.times.to.max))||(pe.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(P(pe.uiOptions.times.to.time))&&(pe.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var fe=null,me=[],pe=this,he={};pe.canManage=!1,pe.calendar={},pe.errors=[],pe.isRequired=!0,pe.requestDayTypes=[],pe.statusNames=u.statusNames,pe.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},pe.pagination={currentPage:1,filteredbreakdown:pe.balance.change.breakdown,numPerPage:7,totalItems:pe.balance.change.breakdown.length,pageChanged:G},pe.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},pe.convertDateFormatFromServer=h,pe.convertDateToServerFormat=v,pe.dateChangeHandler=g,pe.dateTypeChangeHandler=b,pe.daysSelectionModeChangeHandler=y,pe.isLeaveType=N,pe.isNotWorkingDay=F,pe.performBalanceChangeCalculation=Y,pe.$onDestroy=ue,function(){n("RequestModalDetails"+e.capitalize(A(pe.leaveType,pe.request))+"Controller",{detailsController:pe}),pe.canManage=pe.isRole("manager")||pe.isRole("admin"),pe.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",pe),L(),pe.initChildController().then(function(){return s.all([V(),H()])}).then(!pe.isMode("create")&&I).then(ee).then(function(){if(!pe.isMode("create")&&B("hours"))return x().then(oe)}).then(!pe.isMode("create")&&Z).then(M).then(ae).then(T).then(function(){pe.isMode("view")||N("toil")||E()}).catch(S).finally(function(){pe.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","PublicHoliday","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return T.fileUploader&&T.fileUploader.queue.length>0}function f(){return T.getFilesAmount()0?D.map(function(e){return e.label}).join(", "):""}function q(){return T.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(D.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){S[e.label]=t})})).catch(function(){S=null})}function C(){return u.valuesOf("safe_file_extension").then(function(e){D=e})}function w(e){return!e.attachment_id||T.canManage}function A(){e.forEach(R,function(e){e()})}function P(e,t){T.fileUploader.queue&&T.fileUploader.queue.length>0?T.fileUploader.uploadAll({entityID:T.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var D=[],R=[],S={},T=Object.create(this);return T.filesLoaded=!1,T.fileUploader=null,T.today=Date.now(),T.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",T.userDateFormat=s.DATE_FORMAT,T.$onDestroy=A,T.canRemoveAttachment=w,T.canSubmit=d,T.canUploadMore=f,T.formatDateTime=m,T.getAuthorName=p,T.getFilesAmount=h,T.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",T),b(),a.all([C(),q()]).then(y).finally(function(){T.filesLoaded=!0})}(),T}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"},{type:"toil",icon:"calendar-plus-o",label:"Overtime"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{btnClass:"@",contactId:"<",selectedContactId:"<",isSelfRecord:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/manage-leave-requests.component",["common/lodash","leave-absences/shared/modules/components","common/models/contact","common/services/pub-sub"],function(e,t){function n(t,n,a,r,o,s,i,u,c,l,d,f){"use strict";function m(){U.filters.leaveRequest.contact_id=null,U.refresh()}function p(){var e=U.filters.contact;return{department:e.department,level_type:e.level_type,location:e.location,region:e.region}}function h(e){return"all"===e.name||""===e?U.leaveRequests.filter.list.length:U.leaveRequests.filter.list.filter(function(t){return t.status_id===e.value}).length}function v(t){return e.find(U.absenceTypes,{id:t})}function g(e){return new Array(e||0)}function b(t){var n=e.find(U.leaveRequestStatuses,function(e){return e.value===t});return n?n.label:null}function y(e){switch(e){case i.statusNames.approved:return"badge-success";case i.statusNames.rejected:return"badge-danger";case i.statusNames.cancelled:case"all":return"";default:return"badge-primary"}}function _(t){return e.find(U.leaveRequestStatuses,function(e){return e.name===t}).value}function q(t){var n=e.find(U.filteredUsers,function(e){return e.id===t});return n?n.display_name:null}function $(e){return e.current?"Current Period ("+e.title+")":e.title}function C(){return u.all().then(function(t){U.absencePeriods=e.sortBy(t,"start_date"),U.filters.leaveRequest.selectedPeriod=e.find(U.absencePeriods,function(e){return!!e.current})})}function w(){return c.all().then(c.loadCalculationUnits).then(function(e){U.absenceTypes=e})}function A(e){return(U.isAdmin?r.all(p()):r.leaveManagees(U.contactId,p())).then(function(t){return U.filteredUsers=U.isAdmin?t.list:t,e?D(e):n.all([D("table"),D("filter")])}).then(function(){U.filters.leaveRequest.leaveStatus!==H&&0===U.leaveRequests.table.list.length&&U.refresh(1,!0)})}function P(){return s.valuesOf("hrjc_department").then(function(e){U.departments=e})}function D(e){var t="filter"!==e,n="table"===e?e:"content",a="filter"===e?{size:0}:U.pagination,r="filter"===e?{return:["status_id"]}:{};return U.loading[n]=!0,l.all(T(t),a,"from_date DESC",r,!1).then(function(t){U.leaveRequests[e]=t}).catch(function(){U.leaveRequests[e].list=[]}).finally(function(){U.loading[n]=!1})}function R(){return s.valuesOf("hrjc_level_type").then(function(e){U.levelTypes=e})}function S(){return s.valuesOf("hrjc_location").then(function(e){U.locations=e})}function T(t){var n=U.filters.leaveRequest;return{contact_id:M(),managed_by:U.isAdmin&&"me"!==n.assignedTo.type?void 0:U.contactId,status_id:x(t),type_id:n.selectedAbsenceTypes?n.selectedAbsenceTypes.id:{IN:e.pluck(U.absenceTypes,"id")},from_date:{from:n.selectedPeriod.start_date},to_date:{to:n.selectedPeriod.end_date},unassigned:"unassigned"===n.assignedTo.type||void 0}}function I(){return s.valuesOf("hrjc_region").then(function(e){U.regions=e})}function O(){return s.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){U.leaveRequestStatuses=e.concat(U.leaveRequestStatuses)})}function L(e,t,n,a){d.openModal.apply(d,arguments)}function M(){return U.filteredUsers.length>0&&U.filters.leaveRequest.contact_id?U.filters.leaveRequest.contact_id:{IN:U.filteredUsers.map(function(e){return e.id})}}function k(e){var t=[_(i.statusNames.moreInformationRequired),_(i.statusNames.awaitingApproval)];return 0===e.length&&(e=e.concat(t)),e}function x(e){var t=U.filters.leaveRequest,n=[];if(e&&t.leaveStatus&&t.leaveStatus.value&&n.push(t.leaveStatus.value),t.pending_requests&&(n=k(n)),n.length)return{IN:n}}function E(e,t,n){e="number"==typeof e?e:1,t&&(U.filters.leaveRequest.leaveStatus=H),(e<=U.totalNoOfPages()||0===U.totalNoOfPages())&&(U.pagination.page=e,A(n))}function j(e){U.filters.leaveRequest.leaveStatus=e,U.refresh(1,!1,"table")}function B(e){U.filters.leaveRequest.assignedTo=e,U.refresh()}function N(){f.subscribe("LeaveRequest::updatedByManager",function(){U.refresh()}),f.subscribe("LeaveRequest::new",function(){U.refresh()}),f.subscribe("LeaveRequest::edit",function(){U.refresh()}),f.subscribe("LeaveRequest::delete",function(){U.refresh()}),f.subscribe("LeaveRequest::statusUpdate",function(){U.refresh()})}function F(){return Math.ceil(U.leaveRequests.table.total/U.pagination.size)}t.debug("Component: manage-leave-requests");var U=this,H={name:"all",label:"All"};U.absencePeriods=[],U.absenceTypes=[],U.filteredUsers=[],U.isFilterExpanded=!1,U.isAdmin=!1,U.leaveRequests={table:{list:[]},filter:{list:[]}},U.leaveRequestStatuses=[H],U.loading={content:!0,page:!0,table:!0},U.pagination={page:1,size:7},U.filtersByAssignee=[{type:"me",label:"Assigned To Me"},{type:"unassigned",label:"Unassigned"},{type:"all",label:"All"}],U.filters={contact:{department:null,level_type:null,location:null,region:null},leaveRequest:{leaveStatus:U.leaveRequestStatuses[0],pending_requests:!0,contact_id:null,selectedPeriod:null,selectedAbsenceTypes:null,assignedTo:U.filtersByAssignee[0]}},U.clearStaffSelection=m,U.countLeaveRequestByStatus=h,U.getAbsenceTypeByID=v,U.getArrayOfSize=g,U.getLeaveStatusByValue=b,U.getNavBadge=y,U.getUserNameByID=q,U.labelPeriod=$,U.openLeavePopup=L,U.refresh=E,U.refreshWithFilter=j,U.refreshWithFilterByAssignee=B,U.totalNoOfPages=F,function(){o(i.permissions.admin.administer).then(function(e){U.isAdmin=e,n.all([C(),w(),I(),P(),S(),R(),O()]).then(function(){U.loading.page=!1,A()}),N()})}()}t.component("manageLeaveRequests",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/manage-leave-requests.html"}],controllerAs:"vm",controller:n}),n.$inject=["$log","$q","$rootScope","Contact","checkPermissions","OptionGroup","shared-settings","AbsencePeriod","AbsenceType","LeaveRequest","LeavePopup","pubSub"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["leave-absences/shared/modules/controllers"],function(e){function t(e,t,n,a){function r(){return a.request.calculateBalanceChange(a.selectedAbsenceType.calculation_unit_name)}function o(){var e=a.request,t=!!e.from_date&&!!e.to_date,n=a.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function s(){return a.canCalculateChange()}function i(){return n.resolve()}t.debug("RequestModalDetailsLeaveController"),a.calculateBalanceChange=r,a.canCalculateChange=o,a.canSubmit=s,a.initChildController=i}e.controller("RequestModalDetailsLeaveController",t),t.$inject=["$controller","$log","$q","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o){function s(){return!(!o.canCalculateChange()||!o.request.sickness_reason)}function i(){return a.all([l(),d()])}function u(t){var n=o.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function c(t){return!!e.find(o.sicknessDocumentTypes,function(e){return e.value===t})}function l(){return r.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){o.sicknessDocumentTypes=e})}function d(){return r.valuesOf("hrleaveandabsences_sickness_reason").then(function(t){o.sicknessReasons=e.indexBy(t,"name")})}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:o}),o.canSubmit=s,o.initChildController=i,o.isChecked=u,o.isDocumentInRequest=c}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s){function i(){return s.balance.change.amount=+s.request.toil_to_accrue,n.resolve(s.balance.change)}function u(){return m().catch(function(e){return e.length&&(s.errors=e),n.reject(e)}).then(function(e){return o.calculateToilExpiryDate(s.request.type_id,e)}).then(function(e){return s.request.toil_expiry_date=e,s.uiOptions.expiryDate=new Date(e),e})}function c(){return!!s.request.toil_to_accrue}function l(){var e=s.uiOptions.multipleDays&&!!s.request.to_date,t=!s.uiOptions.multipleDays&&!!s.request.from_date,n=t||e,a=w.from_date!==s.request.from_date||w.to_date!==s.request.to_date;return s.canDisplayToilExpirationField&&n&&A.hasExpirationFromAdminSettings&&a}function d(){return!!(s.request.from_date&&s.request.to_date&&s.request.toil_duration&&s.request.toil_to_accrue)}function f(){s.request.toil_expiry_date=!1,s.uiOptions.expiryDate=null}function m(){var e=s.uiOptions.multipleDays,t=s.request;return p({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function p(e){if(e.hasErrors){var t="Please select "+e.label+" to find expiry date";return n.reject([t])}return e.value?n.resolve(e.value):n.reject([])}function h(){var e=s.isMode("create")&&A.hasExpirationFromAdminSettings,t=A.hasPreviousExpirationDate,n=s.isLeaveType("toil"),a=s.canManage;s.canDisplayToilExpirationField=n&&(a||e||t)}function v(){return A.hasPreviousExpirationDate=s.isMode("edit")&&!!s.request.toil_expiry_date,o.canExpire(s.request.type_id).then(function(e){A.hasExpirationFromAdminSettings=e})}function g(){return s.request.to_date_type=s.request.from_date_type="1",v().then(h).then(b).then(_)}function b(){s.canManage&&(s.uiOptions.expiryDate=s.convertDateFormatFromServer(s.request.toil_expiry_date))}function y(){s.isMode("view")||a.$watch(function(){return s.request.toil_to_accrue},function(e,t){+e!=+t&&s.performBalanceChangeCalculation()})}function _(){return r.valuesOf("hrleaveandabsences_toil_amounts").then(function(t){s.toilAmounts=e.indexBy(t,"value")})}function q(){w=angular.copy(s.request.attributes())}function $(){return l()?u().catch(n.resolve):n.resolve()}function C(){s.uiOptions.expiryDate&&(s.request.toil_expiry_date=s.convertDateToServerFormat(s.uiOptions.expiryDate))}t.debug("RequestModalDetailsToilController");var w,A={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};s.canDisplayToilExpirationField=!1,s.calculateBalanceChange=i,s.canCalculateChange=c,s.canSubmit=d,s.clearExpiryDate=f,s.initChildController=g,s.onDateChangeExtended=$,s.setDaysSelectionModeExtended=$,s.updateExpiryDate=C,function(){y(),q()}()}t.controller("RequestModalDetailsToilController",n),n.$inject=["$log","$q","$rootScope","api.optionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/absence-period.instance",["leave-absences/shared/modules/models-instances","common/moment","common/models/instances/instance","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriodInstance",["$log","ModelInstance","HR_settings",function(e,n,a){return e.debug("AbsencePeriodInstance"),n.extend({defaultCustomData:function(){return{current:!1}},transformAttributes:function(e){var n=t();return e.current=!1,t(e.start_date).isSameOrBefore(n,"day")&&t(e.end_date).isSameOrAfter(n,"day")&&(e.current=!0),e},isInPeriod:function(e){var n=a.DATE_FORMAT.toUpperCase(),r=t(e,n);return t(this.start_date).isSameOrBefore(r)&&t(this.end_date).isSameOrAfter(r)}})}])}),define("leave-absences/shared/apis/absence-period.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("AbsencePeriodAPI",["$log","api",function(e,t){return e.debug("AbsencePeriodAPI"),t.extend({all:function(t){return e.debug("AbsencePeriodAPI"),this.sendGET("AbsencePeriod","get",t).then(function(e){return e.values})}})}])}), -define("leave-absences/shared/models/absence-period.model",["leave-absences/shared/modules/models","common/moment","leave-absences/shared/modules/shared-settings","leave-absences/shared/instances/absence-period.instance","leave-absences/shared/apis/absence-period.api","common/models/model","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriod",["$log","Model","AbsencePeriodAPI","AbsencePeriodInstance","shared-settings",function(e,n,a,r,o){return e.debug("AbsencePeriod"),n.extend({all:function(e){return a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},current:function(){var e=t().format(o.serverDateFormat),n={start_date:{"<=":e},end_date:{">=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function f(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function m(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,m(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,m(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),f.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={toilDurationHours:"0",toilDurationMinutes:"0",request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},transformAttributes:function(e){var t=Number(e.toil_duration);return t&&(e.toilDurationHours=Math.floor(t/60).toString(),e.toilDurationMinutes=(t%60).toString()),e},updateDuration:function(){this.toil_duration=60*Number(this.toilDurationHours)+Number(this.toilDurationMinutes)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files","toilDurationHours","toilDurationMinutes"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,f,m,p,h,v,g,b,y,_,q,$,C){function w(e){"days"===ke.selectedAbsenceType.calculation_unit_name?delete ke.request[e+"_date_amount"]:delete ke.request[e+"_date_type"]}function A(){["from","to"].forEach(w)}function P(){var e=ke.requestStatuses[_.statusNames.awaitingApproval].value;Se.status_id===e&&e!==ke.request.status_id&&d.publish("ManagerBadge:: Update Count")}function D(){return Me.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function R(){return Me.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return!ke.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function T(){var e=D();return ke.isMode("edit")&&(e=e&&(V()||R())),ke.canManage&&ke.requestStatuses&&(e=e&&!!ke.getStatusFromValue(ke.newStatusOnSave)),(e=e&&!!ke.period.id)&&!ke.isMode("view")}function I(){ke.isSelfRecord?ke.request.status_id=ke.requestStatuses[_.statusNames.awaitingApproval].value:ke.canManage&&(ke.request.status_id=ke.newStatusOnSave||ke.request.status_id)}function O(){if(ke.isMode("edit")&&!ke.isRole("staff")&&"toil"!==F())return ke.request.calculateBalanceChange(ke.selectedAbsenceType.calculation_unit_name).then(function(e){if(+ke.balance.change.amount!=+e.amount)return C.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function L(){ke.errors=[]}function M(){return ke.request.create().then($e).then(function(){me("LeaveRequest::new")})}function k(){ee()&&!ke.isRole("staff")&&(ke.request.change_balance=!0)}function x(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return ke.request.delete().then(function(){ke.dismissModal(),d.publish("LeaveRequest::delete",ke.request)})}})}function E(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(ke.getStatusFromValue(ke.request.status_id).name)}function N(e){return n.map(De[e],function(e){return ke.requestStatuses[e]})}function F(){return ke.request?ke.request.request_type:ke.leaveType||null}function U(){return!ke.request||e.equals({},ke.requestStatuses)?[]:ke.request.status_id?B():N("none")}function H(e){return n.find(ke.requestStatuses,function(t){return t.value===e})}function W(e){ke.errors=n.isArray(e)?e:[e],ke.loading.absenceTypes=!1,ke.submitting=!1}function V(){return!e.equals(Se,ke.request.attributes())||ke.canManage&&ke.newStatusOnSave}function G(){return ke.postContactSelection=!0,ke.staffMemberSelectionComplete=!1,ke.request.contact_id?r.resolve().then(ie).then(ue).then(he).then(ge).then(Z).then(z).then(ke.isMode("edit")?be:n.noop).then(function(){ke.postContactSelection=!1,ke.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Oe)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];De.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],De.awaiting_approval=e,De.more_information_required=e,De.rejected=e,De.approved=e,De.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return ke.canManage?m.find(ke.request.contact_id).then(function(e){ke.contactName=e.display_name}):r.resolve()}function J(){Te.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(he).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",ke.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){W(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){Re++})),s.$on("$destroy",Ce),s.$on("LeaveRequestPopup::addTab",function(e,t){Me.push(t)})}function K(){var e,t;ke.request=ke.leaveRequest||null,e=F(),t=ke.initRequestAttributes(),"leave"===e?ke.request=y.init(t):"sickness"===e?ke.request=q.init(t):"toil"===e&&(ke.request=$.init(t))}function X(){var e={};return ke.request?e=ke.request.attributes():ke.canManage||(e={contact_id:Ie}),e}function Q(){if(Le="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(Le="admin")}).then(function(){return"staff"===Le&&u(_.permissions.ssp.manage).then(function(e){e&&(Le="manager")})}).finally(function(){ke.canManage=ke.isRole("manager")||ke.isRole("admin")})}function Z(){(ke.isRole("admin")||ke.isMode("create")&&ke.isRole("manager"))&&(ke.newStatusOnSave=ke.requestStatuses[_.statusNames.approved].value)}function ee(){return!ke.request.status_id||!n.includes(["cancelled","rejected"],H(ke.request.status_id).name)}function te(e){var t=ke.getStatusFromValue(ke.request.status_id);return!!t&&t.name===e}function ne(e){return ke.request&&ke.request.request_type===e}function ae(e){return ke.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date)&&r.isSameOrBefore(t.end_date)}function oe(e){return Le===e}function se(){return h.all().then(function(e){ke.absencePeriods=e})}function ie(){return v.all(j()).then(v.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return ke.loading.entitlements=!0,g.all({contact_id:ke.request.contact_id,period_id:ke.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){ke.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Ie=e.contactId})}function le(){return ke.selectedContactId?m.find(ke.selectedContactId).then(function(e){ke.managedContacts=[e]}):ke.isRole("admin")?m.all().then(function(e){ke.managedContacts=n.remove(e.list,function(e){return e.id!==Ie})}):m.find(Ie).then(function(e){return e.leaveManagees()}).then(function(e){ke.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){ke.requestStatuses=n.indexBy(e,"name")})}function fe(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function me(e){P(),d.publish(e,ke.request),ke.errors=[],ke.dismissModal()}function pe(){["from","to"].forEach(function(e){ke.request[e+"_date"]=Se[e+"_date"]})}function he(e){if(ke.absenceTypes=fe(Pe.types,e),!ke.absenceTypes.length)return r.reject(Oe)}function ve(){ke.period=n.find(ke.absencePeriods,function(e){return ke.isMode("create")?e.current:re(ke.request,e)})}function ge(){ke.isMode("create")?(ke.selectedAbsenceType=ke.absenceTypes[0],ke.request.type_id=ke.selectedAbsenceType.id):ke.selectedAbsenceType=n.find(ke.absenceTypes,function(e){return e.id===ke.request.type_id})}function be(){Se=e.copy(ke.request.attributes())}function ye(){var e;ke.request.id?(e=[ke.requestStatuses[_.statusNames.approved].value,ke.requestStatuses[_.statusNames.adminApproved].value,ke.requestStatuses[_.statusNames.rejected].value,ke.requestStatuses[_.statusNames.cancelled].value],ke.mode="edit",ke.isRole("staff")&&e.indexOf(ke.request.status_id)>-1&&(ke.mode="view")):ke.mode="create"}function _e(){var e=ke.request.status_id;if(!ke.isMode("view")&&!ke.submitting)return ke.submitting=!0,I(),A(),ke.request.isValid().then(ee()&&O).then(k).then(!ke.request.change_balance&&pe).then(qe).then(function(){return ke.isMode("edit")?Ae():M()}).catch(function(t){ke.request.status_id=e,t&&W(t)}).finally(function(){ke.submitting=!1})}function qe(){return r.all(Me.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===Re&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return Re>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function Ce(){Te.forEach(function(e){e()})}function we(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function Ae(){return ke.request.update().then($e).then(function(){ke.isRole("manager")?me("LeaveRequest::updatedByManager"):(ke.isRole("staff")||ke.isRole("admin"))&&me("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,De={},Re=0,Se={},Te=[],Ie="",Oe="No entitlement",Le="",Me=[],ke=n.assign(this,f);ke.absencePeriods=[],ke.absenceTypes=[],ke.canManage=!1,ke.contactName=null,ke.errors=[],ke.loading={absenceTypes:!0,entitlements:!0},ke.managedContacts=[],ke.mode="",ke.newStatusOnSave=null,ke.period={},ke.postContactSelection=!1,ke.requestStatuses={},ke.selectedAbsenceType={},ke.staffMemberSelectionComplete=!1,ke.submitting=!1,ke.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},ke.canChangeAbsenceType=S,ke.canSubmit=T,ke.closeAlert=L,ke.deleteLeaveRequest=x,ke.dismissModal=E,ke.getStatuses=U,ke.getStatusFromValue=H,ke.initAfterContactSelection=G,ke.initRequestAttributes=X,ke.isLeaveStatus=te,ke.isLeaveType=ne,ke.isMode=ae,ke.isRole=oe,ke.submit=_e,ke.updateAbsenceType=we,function(){ke.loading.absenceTypes=!0,Y(),J(),r.all([ce(),Q(),se(),de()]).then(K).then(ye).then(ve).then(function(){return ke.canManage&&!ke.isMode("edit")&&le()}).then(function(){if(ke.selectedContactId&&(ke.request.contact_id=ke.selectedContactId),ke.request.contact_id)return ke.initAfterContactSelection()}).catch(W).finally(function(){ke.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),function(e){define("leave-absences/admin-dashboard/modules/settings",["common/angular"],function(t){return t.module("admin-dashboard.settings",[]).constant("settings",{contactId:e.vars.leaveAndAbsences.loggedInUserId,debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/admin-dashboard/"})})}(CRM),define("leave-absences/admin-dashboard/modules/config",["common/angular","leave-absences/admin-dashboard/modules/settings"],function(e){return e.module("admin-dashboard.config",["admin-dashboard.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(e,t,n,a,r,o){var s={format:["DateFormat",function(e){return e.getDateFormat()}]};r.debugEnabled(o.debug),t.defaults.stripTrailingSlashes=!1,a.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",n.otherwise("/requests"),e.state("requests",{url:"/requests",template:'',resolve:s}).state("calendar",{url:"/calendar",template:'',resolve:s}).state("leave-balances",{url:"/leave-balances",template:"",resolve:s})}])}),define("leave-absences/admin-dashboard/modules/components",["common/angular"],function(e){return e.module("admin-dashboard.components",[])}),define("leave-absences/admin-dashboard/components/admin-dashboard-container",["leave-absences/admin-dashboard/modules/components"],function(e){function t(e,t){e.debug("Component: admin-dashboard-container"),t.section="admin-dashboard"}e.component("adminDashboardContainer",{templateUrl:["settings",function(e){return e.pathTpl+"components/admin-dashboard-container.html"}],controllerAs:"vm",controller:["$log","$rootScope",t]})}), -define("leave-absences/admin-dashboard/app",["common/angular","common/angularBootstrap","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/services/check-permissions","common/services/angular-date/date-format","leave-absences/shared/ui-router","leave-absences/shared/components/leave-balance-tab.component","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/manage-leave-requests.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/admin-dashboard/modules/config","leave-absences/admin-dashboard/components/admin-dashboard-container"],function(e){return e.module("admin-dashboard",["ngAnimate","ngResource","ui.bootstrap","ui.router","ui.select","textAngular","common.angularDate","common.dialog","common.filters","common.mocks","leave-absences.components","leave-absences.controllers","leave-absences.settings","leave-absences.services","admin-dashboard.config","admin-dashboard.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/admin-dashboard":n+"/admin-dashboard"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/admin-dashboard/app"],function(){document.dispatchEvent("function"==typeof window.CustomEvent?new CustomEvent("adminDashboardReady"):function(){var e=document.createEvent("Event");return e.initEvent("adminDashboardReady",!0,!0),e}())})})}(CRM,require),define("admin-dashboard",function(){}); +!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return W(new(W(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[f]),c[r[f]]=e[r[f]]);return W({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))v.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&m(u[e],e)}),v.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var h=s(u||{}),v=[],g=[],b={};return H(u,m),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),m.$$values=b,m.$$promises=m.$$promises||!0,delete m.$$inheritedValues,c.resolve(b))}function u(e){m.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),m=c.promise,g=m.$$promises={},b=W({},a),y=1+v.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),m;o.$$inheritedValues&&r(b,f(o.$$inheritedValues,h)),W(g,o.$$promises),o.$$values?(_=r(b,f(o.$$values,h)),m.$$inheritedValues=f(o.$$values,h),i()):(o.$$inheritedValues&&(m.$$inheritedValues=f(o.$$inheritedValues,h)),o.then(i,u));for(var q=0,$=v.length;q<$;q+=3)a.hasOwnProperty(v[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(m.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),f=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(f++,g[e].then(function(t){b[e]=t,--f||l()},c))}),f||l(),g[n]=d.promise}(v[q],v[q+1],v[q+2]);return m}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(v.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(h[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return h[t]=new Y.Param(t,n,a,r),h[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(f,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=W({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",f=0,m=this.segments=[],p=r?r.params:{},h=this.params=r?r.params.$$new():new Y.ParamSet,v=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),m.push(g.segment),f=c.lastIndex;y=e.substring(f);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,f+_),q.length>0)for(f=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),f=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",m.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=m[0],this.$$paramNames=v}function y(e){W(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:h,caseInsensitive:f}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){W(this,e||{})}Y=this;var d,f=!1,h=!0,v=!1,g={},q=!0,$=[],C={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(f=e),f},this.strictMode=function(e){return j(e)&&(h=e),h},this.defaultSquashPolicy=function(e){if(!j(e))return v;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return v=e,e},this.compile=function(e,t){return new b(e,W(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(W({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(C,function(e,t){g[t]=new y(W({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(C,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!h.type.is(e))throw new Error("Default value ("+e+") for parameter '"+h.id+"' is not an instance of Type ("+h.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(m(h.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?h.type.$normalize(e):c()}function f(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var h=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return W(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return v;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),m(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);W(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:f})},l.prototype={$$new:function(){return a(this,W(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return m(r,t.self);for(var o in S)B(S[o])&&(t[o]=S[o](t,S.$delegates[o]));return P[n]=t,!t[R]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){w.$current.navigable==t&&c(e,n)||w.transitionTo(t,e,{inherit:!0,location:!1})}]),v(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=w.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=x[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(w.$current=t,w.current=t.self,w.params=n,V(w.params,m),w.transition=null,o.location&&t.navigable&&v.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),v.update(!0),w.current)}).then(null,function(a){return a===D?S:w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(w.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||v.update(),r.reject(a))});return B},w.is=function(e,t,a){a=W({relative:w.$current},a||{});var r=f(e,a.relative);return j(r)?w.$current===r&&(!t||c(r.params.$$values(t),m)):n},w.includes=function(e,t,a){if(a=W({relative:w.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=w.$current.name}var r=f(e,a.relative);if(!j(r))return n;if(!j(w.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(f&&(f.remove(),f=null),p&&(p.$destroy(),p=null),m){var e=m.data("$uiViewAnim");b.leave(m,function(){e.$$animLeave.resolve(),f=null}),f=m,m=null}}function d(s){var d,f=D(n,c,i,r),y=f&&e.$current&&e.$current.locals[f];if(s||y!==h){d=n.$new(),h=e.$current.locals[f],d.$emit("$viewContentLoading",f);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});m=_,p=d,p.$emit("$viewContentLoaded",f),p.$eval(v)}}var f,m,p,h,v=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=D(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var f=t.extend({},d);o[d.$$resolveAs]=f;var m=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=f),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}m(o)}}}}}function D(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function R(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function S(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function T(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function O(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function I(e,t){return{relative:S(e)||t.$current,inherit:!0}}function E(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=R(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=T(r),d=s[1]||s[0],f=null;c.options=W(I(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var m=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),f&&f(),d&&(f=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&m(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),m(),l.clickable&&(i=O(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function x(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){f.state=t[0],f.params=t[1],f.options=t[2],f.href=e.href(f.state,f.params,f.options),m&&m(),c&&(m=c.$$addStateInfo(f.state,f.params)),f.href&&r.$set(u.attr,f.href)}var i,u=T(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",f={state:null,params:null,options:null,href:null},m=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=O(a,e,t,u,function(){return f}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function M(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,S(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return h.push(u),v[s]=r,function(){var e=h.indexOf(u);-1!==e&&h.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function L(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function k(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,W=t.extend,V=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),v.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",v),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,W(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;aWhen All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,f){function m(){for(var e=[],t=n(x.selectedPeriod.start_date).clone().startOf("month"),a=n(x.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");x.months=e}function p(){s.$new().$watch(function(){return x.selectedMonths},function(t,n){null===n||e.equals(t,n)||R()})}function h(e){x.injectMonths=!0,O("injected").then(function(){R(e)}).then(function(){x.loading.calendar=!1})}function v(){I=a("LeaveCalendar"+t.capitalize(E)+"Controller").init(x)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){x.absencePeriods=t.sortBy(e,"start_date"),x.selectedPeriod=t.find(x.absencePeriods,function(e){return!!e.current})}).then(m).then(S)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return I.loadContacts().then(function(e){x.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){x.filters.optionValues.regions=e.hrjc_region,x.filters.optionValues.locations=e.hrjc_location,x.filters.optionValues.levelTypes=e.hrjc_level_type,x.filters.optionValues.departments=e.hrjc_department})}function C(){return l.all()}function A(){return r.all([y(),C(),_()]).then(function(e){x.supportData.absenceTypes=e[0],x.supportData.publicHolidays=e[1],x.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,x.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,x.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,x.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function w(){var e=r.resolve();return x.injectMonths&&(e=O("destroyed"),x.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function D(e){e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){x.loading.calendar=!0}).then(w).then("period"===e?m:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function R(e){var n=x.selectedMonths.length?x.months.filter(function(e){return t.includes(x.selectedMonths,e.index)}):x.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function S(){x.selectedMonths=[n().month()]}function T(){return x.roleOverride?r.resolve().then(function(){E=x.roleOverride}):r.all([f(i.permissions.admin.administer),f(i.permissions.ssp.manage)]).then(function(e){E=e[0]?"admin":e[1]?"manager":"staff"})}function O(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===x.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var I,E,x=this;x.absencePeriods=[],x.contacts=[],x.contactIdsToReduceTo=null,x.injectMonths=!1,x.months=[],x.selectedMonths=null,x.selectedPeriod=null,x.showContactName=!1,x.showFilters=!1,x.supportData={},x.loading={calendar:!0,page:!0},x.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},x.labelPeriod=g,x.refresh=D,function(){T().then(p).then(v).then(w).then(b).then(function(){return r.all([q(),A()])}).then(function(){return x.showFilters?$():t.noop}).then(function(){h()}).then(function(){x.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r,o){"use strict";function s(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function i(e){return e.isAM?"AM":e.isPM?"PM":""}function u(e){var n=t(e.from_date).isSame(g.date,"day"),a=t(e.to_date).isSame(g.date,"day");return n?t(e.from_date).format("HH:mm"):a?t(e.to_date).format("HH:mm"):""}function c(t,n){g.contactData.leaveRequestsAttributes[t.id].absenceTypeTitle=e.find(g.supportData.absenceTypes,{id:t.type_id}).title}function l(t,n){var a=e.find(g.supportData.absenceTypes,{id:t.type_id}),r=e.find(g.supportData.calculationUnits,{value:a.calculation_unit});n.unit=r.name}function d(e,t){t.from_date=new Date(e.from_date),t.to_date=new Date(e.to_date)}function f(t,n){"days"===n.unit&&(n.from_date_type=e.find(g.supportData.dayTypes,{value:t.from_date_type}).label,n.to_date_type=e.find(g.supportData.dayTypes,{value:t.to_date_type}).label)}function m(e,t){var n="";n=t.isAccruedTOIL?"AT":"days"===t.unit?i(t):u(e),t.label=n}function p(e){var t=g.contactData.leaveRequestsAttributes[e.id];[l,f,m,d,c].forEach(function(n){n.call(this,e,t)})}function h(e,t){r(function(){g.tooltip[e+"_hovered"]=t,g.tooltip.show=g.tooltip.day_cell_hovered||g.tooltip.tooltip_hovered},t?0:100)}function v(){a.$watch("day.contactData.leaveRequests",function(){g.contactData&&g.contactData.leaveRequests&&g.contactData.leaveRequests.forEach(p)},!0)}n.debug("Component: leave-calendar-day");var g=this;g.tooltip={show:!1,day_cell_hovered:!1,tooltip_hovered:!1},g.openLeavePopup=s,g.toggleTooltip=h,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","$timeout","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){q([e]),U(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(Y.period.start_date)&&r.isSameOrBefore(Y.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function f(e){return V[e]}function m(){return Y.showOnlyWithLeaveRequests?Y.contacts.filter(function(e){return Object.keys(G[e.id]||{}).length}):Y.contacts}function p(e){return t(e,u.serverDateFormat)}function h(e){var t=g(e);t&&(x(t),U(t))}function v(t){var n={request_type:"toil"};return e.some(t,n)&&!e.every(t,n)?e.filter(t,n):t}function g(t){var n;return e.find(G[t.contact_id],function(a){return n=e.find(a,function(e){return+e.id==+t.id})}),n}function b(e){return CRM.url("civicrm/contact/view",{cid:e})}function y(e,n){var a={};return n.forEach(function(n){a[n.id]={styles:N(n),isAccruedTOIL:A(n,"toil"),isRequested:P(n),isAM:C("half_day_am",n,e.date),isPM:C("half_day_pm",n,e.date),isSingleDay:t(n.from_date).isSame(n.to_date,"day")}}),a}function _(){Y.supportData.dayTypes=e.indexBy(Y.supportData.dayTypes,"name"),Y.supportData.leaveRequestStatuses=e.indexBy(Y.supportData.leaveRequestStatuses,"value"),Y.supportData.publicHolidays=e.transform(Y.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function q(e){return e.forEach(function(e){var t=D(e);G[e.contact_id]=G[e.contact_id]||{},t.forEach(function(t){G[e.contact_id][t.date]||(G[e.contact_id][t.date]=[]),G[e.contact_id][t.date].push(e)})}),a.resolve()}function $(){W.push(r.$on("LeaveCalendar::showMonths",j)),W.push(i.subscribe("LeaveRequest::new",c)),W.push(i.subscribe("LeaveRequest::edit",F)),W.push(i.subscribe("LeaveRequest::updatedByManager",F)),W.push(i.subscribe("LeaveRequest::delete",h)),W.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):F(e.leaveRequest)}))}function C(e,n,a){var r=Y.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function A(e,t){return e.request_type===t}function w(e){return!!Y.supportData.publicHolidays[p(e).valueOf()]}function P(t){var n=Y.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function D(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===Y.month.index&&r.year()===Y.month.year&&a.push(e.find(Y.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function R(t){var n=e.find(Y.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function S(){return[R(u.statusNames.approved),R(u.statusNames.adminApproved),R(u.statusNames.awaitingApproval),R(u.statusNames.moreInformationRequired)]}function T(){return Y.month.loading=!0,a.all([I(),O()]).then(E).then(k).then(function(){H=!0,Y.month.loading=!1})}function O(){return s.all({from_date:{to:Y.month.days[Y.month.days.length-1].date},to_date:{from:Y.month.days[0].date},status_id:{IN:S()},contact_id:{IN:Y.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(Y.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return q(e.list)})}function I(){var t=Y.month.days[0].date,n=Y.month.days[Y.month.days.length-1].date;return o.get(Y.contacts.map(function(e){return e.id}),t,n).then(function(t){V=e.indexBy(t,"contact_id")})}function E(){return Y.contactIdsToReduceTo&&(Y.contacts=Y.contacts.filter(function(t){return e.includes(Y.contactIdsToReduceTo,t.contact_id)||e.find(G,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function x(t){var n=D(t);G[t.contact_id]=G[t.contact_id]||{},n.forEach(function(n){e.remove(G[t.contact_id][n.date],function(e){return e.id===t.id})})}function M(){r.$emit("LeaveCalendar::monthDestroyed"),W.map(function(e){e.remove?e.remove():e()})}function L(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=f(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:w(t.date)})}),o.then(function(){return G[n]&&G[n][t.date]?G[n][t.date]:[]}).then(function(a){a=B(a),e.assign(t.contactsData[n],{leaveRequests:a,leaveRequestsToShowInCell:v(a),leaveRequestsAttributes:y(t,a)})})}function k(){return a.all(Y.month.days.map(function(e){return a.all(Y.contacts.map(function(t){return L(e,t.id)}))}))}function j(t,n,a){!e.find(n,function(e){return e.index===Y.month.index})?Y.visible=!1:(Y.currentPage=0,Y.visible=!0,(a||!H)&&T())}function B(n){return e.sortBy(n,function(e){return+t(e.from_date).format("X")+(C("half_day_pm",e,e.from_date)?1:0)})}function N(t){var n=e.find(Y.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function F(e){h(e),-1!==S().indexOf(e.status_id)&&c(e)}function U(e){return a.all(D(e).map(function(t){return L(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var H=!1,W=[],V={},G={},Y=this;Y.currentPage=0,Y.pageSize=20,Y.visible=!1,Y.showContactName=!!Y.showContactName,Y.showOnlyWithLeaveRequests=!!Y.showOnlyWithLeaveRequests,Y.$onDestroy=M,Y.contactsList=m,Y.getContactUrl=b,function(){var e=t().month(Y.month.index).year(Y.month.year);_(),$(),Y.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o,promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(h(t)):m(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function f(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||("manager"===q.role?e.includes([$.awaitingApproval,$.moreInformationRequired],n):"3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a)}function m(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=C[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function v(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(C,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!f(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:C[e].label,isDirectAction:C[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,C={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}), +a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function f(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function m(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=f,q.getActiveComments=m,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f){function m(){te.balance.closing=te.balance.opening+te.balance.change.amount}function p(e){return t(e,u.serverDateFormat).toDate()}function h(e){return t(e).format(u.serverDateFormat)}function v(e){var t;return s.resolve().then(function(){F(e),"from"===e&&N(),O("hours")&&(y(e),"from"!==e||te.uiOptions.multipleDays||y("to")),te.loading[e+"DayTypes"]=!0}).then(function(){return q(e)}).then(function(e){if(t=e.id!==te.period.id,t&&(te.period=e),!te.period.id)return s.reject("Please change date as it is not in any absence period")}).then(H).then(function(){if(t)return M()}).then(function(){return te.onDateChangeExtended&&te.onDateChangeExtended(e)}).then(function(){if(Y(),!t)return k();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(w).finally(_)}function g(){return Y(),k()}function b(){return te.uiOptions.toDate=null,F("to"),s.resolve().then(Y).then(te.setDaysSelectionModeExtended).then(_).then(!te.uiOptions.multipleDays&&k)}function y(e){te.uiOptions.times[e].loading=!0}function _(){["from","to"].forEach(function(e){te.loading[e+"DayTypes"]=!1,O("hours")&&(te.uiOptions.times[e].loading=!1)})}function q(n){var a=t(te.uiOptions[n+"Date"]).format(te.uiOptions.userDateFormat.toUpperCase());return e.find(te.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function $(){return te.request?te.request.request_type:te.leaveType||null}function C(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function A(){return z(),te.loading.balanceChange=!0,te.request.getBalanceChangeBreakdown().then(U).catch(w)}function w(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),te.loading.fromDayTypes=!1,te.loading.balanceChange=!1,te.loading.tab=!1,te.loading.toDayTypes=!1}function P(){return te.isMode("create")||te.forceRecalculateBalanceChange?k():A()}function D(){var e=te.request.attributes();return te.uiOptions.fromDate=p(te.request.from_date),te.request.to_date=e.to_date,te.request.to_date_type=e.to_date_type,te.uiOptions.toDate=p(te.request.to_date),te.initDayTypesExtended?te.initDayTypesExtended():s.resolve()}function R(){ee.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){J()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){K(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",k))}function S(){te.isMode("edit")&&(te.isLeaveStatus(u.statusNames.approved)||te.isLeaveStatus(u.statusNames.adminApproved))&&(Z={absenceTypeId:te.request.type_id,value:te.selectedAbsenceType.remainder-te.request.balance_change})}function T(){r.$watch(function(){return te.uiOptions.times.from.time},function(e,t){e!==t&&(te.uiOptions.multipleDays||(Q(e),Y()))})}function O(e){return te.selectedAbsenceType.calculation_unit_name===e}function I(e){return te.request.request_type===e}function E(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function x(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){te.requestDayTypes=e})}function M(){return c.get(te.request.contact_id,te.period.start_date,te.period.end_date).then(function(e){te.calendar=e})}function L(){var e=(te.pagination.currentPage-1)*te.pagination.numPerPage,t=e+te.pagination.numPerPage;te.pagination.filteredbreakdown=te.balance.change.breakdown.slice(e,t)}function k(){return z(),te.canCalculateChange()?(te.loading.balanceChange=!0,te.request.change_balance=!0,te.calculateBalanceChange().then(U).catch(w).finally(function(){te.loading.balanceChange=!1})):s.resolve()}function j(){te.pagination.totalItems=te.balance.change.breakdown.length,te.pagination.filteredbreakdown=te.balance.change.breakdown,te.pagination.pageChanged()}function B(){return h(te.request.from_date)===h(te.request.to_date)}function N(){te.uiOptions.toDate&&te.uiOptions.fromDate&&te.uiOptions.multipleDays&&t(te.uiOptions.toDate).isSameOrBefore(te.uiOptions.fromDate)&&(te.uiOptions.toDate=null,F("to"))}function F(e){te.resetUIInputsExtended&&te.resetUIInputsExtended(e),Y(),z()}function U(e){te.balance.change=e,te.request.balance_change=e.amount,m(),j(),te.loading.balanceChange=!1}function H(){var e,n,a;te.uiOptions.fromDate?(e=t(te.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=p(te.period.start_date),n=te.uiOptions.date.to.options.minDate),te.uiOptions.date.to.options.initDate=n,te.uiOptions.date.to.options.minDate=a,te.uiOptions.date.to.options.maxDate=p(te.period.end_date)}function W(){return!te.isMode("create")&&B()||te.isMode("create")&&(I("sickness")||O("hours"))?te.uiOptions.multipleDays=!1:te.uiOptions.multipleDays=!0,s.resolve().then(te.setDaysSelectionModeExtended)}function V(){Z&&Z.absenceTypeId===te.selectedAbsenceType.id?te.balance.opening=Z.value||0:te.balance.opening=te.selectedAbsenceType.remainder}function G(){te.selectedAbsenceType=e.find(te.absenceTypes,function(e){return e.id===te.request.type_id})}function Y(){var e=te.uiOptions,t=e.times;te.request.from_date=e.fromDate?h(e.fromDate):null,te.request.to_date=e.toDate?h(e.toDate):null,!e.multipleDays&&e.fromDate&&(te.request.to_date=te.request.from_date,te.request.to_date_type=te.request.from_date_type),(O("hours")||I("toil"))&&(te.request.from_date=te.request.from_date&&t.from.time?te.request.from_date+" "+t.from.time:null,te.request.to_date=te.request.to_date&&t.to.time?te.request.to_date+" "+t.to.time:null)}function z(){te.uiOptions.showBalance=te.canCalculateChange()}function X(){e.forEach(ee,function(e){e()})}function J(){var e,t=te.selectedAbsenceType.calculation_unit_name;return G(),e=t!==te.selectedAbsenceType.calculation_unit_name,V(),s.resolve().then(e&&W).then(e&&te.onAbsenceTypeUpdateExtended).then(e&&Y).then(_).then(k)}function K(e){return te.absenceTypes=e,G(),t(te.uiOptions.toDate).isAfter(te.period.end_date)&&(te.uiOptions.toDate=void 0,F("to")),V(),k()}function Q(e){var t=C(e).add(te.uiOptions.time_interval,"minutes");t.isAfter(C(te.uiOptions.times.to.max))||(te.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(C(te.uiOptions.times.to.time))&&(te.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var Z=null,ee=[],te=this;te.canManage=!1,te.calendar={},te.errors=[],te.isRequired=!0,te.requestDayTypes=[],te.statusNames=u.statusNames,te.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},te.pagination={currentPage:1,filteredbreakdown:te.balance.change.breakdown,numPerPage:7,totalItems:te.balance.change.breakdown.length,pageChanged:L},te.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},te.convertDateFormatFromServer=p,te.convertDateToServerFormat=h,te.dateChangeHandler=v,te.dateTypeChangeHandler=g,te.daysSelectionModeChangeHandler=b,te.disableAndShowLoadingTimeInput=y,te.getMomentDateWithGivenTime=C,te.handleError=w,te.isCalculationUnit=O,te.isLeaveType=I,te.isNotWorkingDay=E,te.performBalanceChangeCalculation=k,te.setRequestDateTimesAndDateTypes=Y,te.updateEndTimeInputMinTime=Q,te.$onDestroy=X,function(){n("RequestModalDetails"+e.capitalize($(te.leaveType,te.request))+"Controller",{detailsController:te}),te.canManage=te.isRole("manager")||te.isRole("admin"),te.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",te),R(),te.initChildController().then(function(){return s.all([M(),x()])}).then(!te.isMode("create")&&D).then(W).then(function(){if(!te.isMode("create"))return s.resolve().then(te.initTimesExtended).then(Y)}).then(!te.isMode("create")&&H).then(S).then(V).then(P).then(T).then(!te.isMode("view")&&te.initWatchersExtended).catch(w).finally(function(){te.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return T.fileUploader&&T.fileUploader.queue.length>0}function f(){return T.getFilesAmount()0?D.map(function(e){return e.label}).join(", "):""}function q(){return T.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(D.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){S[e.label]=t})})).catch(function(){S=null})}function C(){return u.valuesOf("safe_file_extension").then(function(e){D=e})}function A(e){return!e.attachment_id||T.canManage}function w(){e.forEach(R,function(e){e()})}function P(e,t){T.fileUploader.queue&&T.fileUploader.queue.length>0?T.fileUploader.uploadAll({entityID:T.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var D=[],R=[],S={},T=Object.create(this);return T.filesLoaded=!1,T.fileUploader=null,T.today=Date.now(),T.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",T.userDateFormat=s.DATE_FORMAT,T.$onDestroy=w,T.canRemoveAttachment=A,T.canSubmit=d,T.canUploadMore=f,T.formatDateTime=m,T.getAuthorName=p,T.getFilesAmount=h,T.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",T),b(),a.all([C(),q()]).then(y).finally(function(){T.filesLoaded=!0})}(),T}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{contactId:"<",isSelfRecord:"<",selectedContactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/manage-leave-requests.component",["common/lodash","leave-absences/shared/modules/components","common/models/contact","common/services/pub-sub"],function(e,t){function n(t,n,a,r,o,s,i,u,c,l,d,f){"use strict";function m(){U.filters.leaveRequest.contact_id=null,U.refresh()}function p(){var e=U.filters.contact;return{department:e.department,level_type:e.level_type,location:e.location,region:e.region}}function h(e){return"all"===e.name||""===e?U.leaveRequests.filter.list.length:U.leaveRequests.filter.list.filter(function(t){return t.status_id===e.value}).length}function v(t){return e.find(U.absenceTypes,{id:t})}function g(e){return new Array(e||0)}function b(t){var n=e.find(U.leaveRequestStatuses,function(e){return e.value===t});return n?n.label:null}function y(e){switch(e){case i.statusNames.approved:return"badge-success";case i.statusNames.rejected:return"badge-danger";case i.statusNames.cancelled:case"all":return"";default:return"badge-primary"}}function _(t){return e.find(U.leaveRequestStatuses,function(e){return e.name===t}).value}function q(t){var n=e.find(U.filteredUsers,function(e){return e.id===t});return n?n.display_name:null}function $(e){return e.current?"Current Period ("+e.title+")":e.title}function C(){return u.all().then(function(t){U.absencePeriods=e.sortBy(t,"start_date"),U.filters.leaveRequest.selectedPeriod=e.find(U.absencePeriods,function(e){return!!e.current})})}function A(){return c.all().then(c.loadCalculationUnits).then(function(e){U.absenceTypes=e})}function w(e){return(U.isAdmin?r.all(p()):r.leaveManagees(U.contactId,p())).then(function(t){return U.filteredUsers=U.isAdmin?t.list:t,e?D(e):n.all([D("table"),D("filter")])}).then(function(){U.filters.leaveRequest.leaveStatus!==H&&0===U.leaveRequests.table.list.length&&U.refresh(1,!0)})}function P(){return s.valuesOf("hrjc_department").then(function(e){U.departments=e})}function D(e){var t="filter"!==e,n="table"===e?e:"content",a="filter"===e?{size:0}:U.pagination,r="filter"===e?{return:["status_id"]}:{};return U.loading[n]=!0,l.all(T(t),a,"from_date DESC",r,!1).then(function(t){U.leaveRequests[e]=t}).catch(function(){U.leaveRequests[e].list=[]}).finally(function(){U.loading[n]=!1})}function R(){return s.valuesOf("hrjc_level_type").then(function(e){U.levelTypes=e})}function S(){return s.valuesOf("hrjc_location").then(function(e){U.locations=e})}function T(t){var n=U.filters.leaveRequest;return{contact_id:x(),managed_by:U.isAdmin&&"me"!==n.assignedTo.type?void 0:U.contactId,status_id:L(t),type_id:n.selectedAbsenceTypes?n.selectedAbsenceTypes.id:{IN:e.pluck(U.absenceTypes,"id")},from_date:{from:n.selectedPeriod.start_date},to_date:{to:n.selectedPeriod.end_date},unassigned:"unassigned"===n.assignedTo.type||void 0}}function O(){return s.valuesOf("hrjc_region").then(function(e){U.regions=e})}function I(){return s.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){U.leaveRequestStatuses=e.concat(U.leaveRequestStatuses)})}function E(e,t,n,a){d.openModal.apply(d,arguments)}function x(){return U.filteredUsers.length>0&&U.filters.leaveRequest.contact_id?U.filters.leaveRequest.contact_id:{IN:U.filteredUsers.map(function(e){return e.id})}}function M(e){var t=[_(i.statusNames.moreInformationRequired),_(i.statusNames.awaitingApproval)];return 0===e.length&&(e=e.concat(t)),e}function L(e){var t=U.filters.leaveRequest,n=[];if(e&&t.leaveStatus&&t.leaveStatus.value&&n.push(t.leaveStatus.value),t.pending_requests&&(n=M(n)),n.length)return{IN:n}}function k(e,t,n){e="number"==typeof e?e:1,t&&(U.filters.leaveRequest.leaveStatus=H),(e<=U.totalNoOfPages()||0===U.totalNoOfPages())&&(U.pagination.page=e,w(n))}function j(e){U.filters.leaveRequest.leaveStatus=e,U.refresh(1,!1,"table")}function B(e){U.filters.leaveRequest.assignedTo=e,U.refresh()}function N(){f.subscribe("LeaveRequest::updatedByManager",function(){U.refresh()}),f.subscribe("LeaveRequest::new",function(){U.refresh()}),f.subscribe("LeaveRequest::edit",function(){U.refresh()}),f.subscribe("LeaveRequest::delete",function(){U.refresh()}),f.subscribe("LeaveRequest::statusUpdate",function(){U.refresh()})}function F(){return Math.ceil(U.leaveRequests.table.total/U.pagination.size)}t.debug("Component: manage-leave-requests");var U=this,H={name:"all",label:"All"};U.absencePeriods=[],U.absenceTypes=[],U.filteredUsers=[],U.isFilterExpanded=!1,U.isAdmin=!1,U.leaveRequests={table:{list:[]},filter:{list:[]}},U.leaveRequestStatuses=[H],U.loading={content:!0,page:!0,table:!0},U.pagination={page:1,size:7},U.filtersByAssignee=[{type:"me",label:"Assigned To Me"},{type:"unassigned",label:"Unassigned"},{type:"all",label:"All"}],U.filters={contact:{department:null,level_type:null,location:null,region:null},leaveRequest:{leaveStatus:U.leaveRequestStatuses[0],pending_requests:!0,contact_id:null,selectedPeriod:null,selectedAbsenceTypes:null,assignedTo:U.filtersByAssignee[0]}},U.clearStaffSelection=m,U.countLeaveRequestByStatus=h,U.getAbsenceTypeByID=v,U.getArrayOfSize=g,U.getLeaveStatusByValue=b,U.getNavBadge=y,U.getUserNameByID=q,U.labelPeriod=$,U.openLeavePopup=E,U.refresh=k,U.refreshWithFilter=j,U.refreshWithFilterByAssignee=B,U.totalNoOfPages=F,function(){o(i.permissions.admin.administer).then(function(e){U.isAdmin=e,n.all([C(),A(),O(),P(),S(),R(),I()]).then(function(){U.loading.page=!1,w()}),N()})}()}t.component("manageLeaveRequests",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/manage-leave-requests.html"}],controllerAs:"vm",controller:n}),n.$inject=["$log","$q","$rootScope","Contact","checkPermissions","OptionGroup","shared-settings","AbsencePeriod","AbsenceType","LeaveRequest","LeavePopup","pubSub"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return s.request.calculateBalanceChange(s.selectedAbsenceType.calculation_unit_name)}function l(){var e=s.request,t=!!e.from_date&&!!e.to_date,n=s.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function d(){return s.canCalculateChange()}function f(t,n){var a=s.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);s.uiOptions.multipleDays||("from"===t&&o&&r&&(o=s.getMomentDateWithGivenTime(o).subtract(s.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=s.getMomentDateWithGivenTime(r).add(s.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min}function m(t,n){return t?(t=s.convertDateToServerFormat(t),v(t).then(function(n){return n?s.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):p(t,s.requestDayTypes).then(function(t){return t.length?t:s.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return R(n,e),e})):r.reject([])}function p(e,n){return e=t(e),r.all([s.calendar.isNonWorkingDay(e),s.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function h(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function v(e){return u.all({public_holiday:1,contact_id:s.request.contact_id,from_date:{from:e},to_date:{to:e}}).then(function(e){return!!e.list.length})}function g(){return r.resolve()}function b(){return A(s.uiOptions.fromDate,"from").then(function(){return A(s.uiOptions.toDate,"to")})}function y(e){o.$watch(function(){return s.uiOptions.times[e].amount},function(e,t){s.isCalculationUnit("days")||+e==+t||(s.isRole("staff")&&(s.request.change_balance=!0),O(),s.performBalanceChangeCalculation())})}function _(e){var n=t(s.request[e+"_date"]).format("HH:mm"),a=s.uiOptions.times[e];(h(a.min,n)<=0||h(a.max,n)>=0)&&(n="from"===e?a.min:a.max),s.uiOptions.times[e].time=n}function q(){var e=s.uiOptions.multipleDays?["from","to"]:["from"],t=s.uiOptions.times;if(s.isCalculationUnit("hours"))return r.all(e.map(P)).then(function(){["from","to"].forEach(function(e){_(e),T(e),t[e].amount=Math.min(s.request[e+"_date_amount"],t[e].maxAmount).toString()}),s.uiOptions.multipleDays||s.updateEndTimeInputMinTime(s.uiOptions.times.from.time)}).then(O)}function $(){["from","to"].forEach(function(e){y(e),C(e)})}function C(e){o.$watch(function(){return s.uiOptions.times[e].time},function(t,n){s.isCalculationUnit("days")||t===n||(s.setRequestDateTimesAndDateTypes(),t&&T(e,!0))})}function A(e,t){return m(e,t).then(function(){s.loading[t+"DayTypes"]=!1})}function w(e){return A(s.uiOptions[e+"Date"],e).then(function(){if(s.isCalculationUnit("hours"))return P(e).then(function(){T(e,!0)})})}function P(e){var t=s.uiOptions[e+"Date"],n=!s.uiOptions.multipleDays;return t?s.request.getWorkDayForDate(s.convertDateToServerFormat(t)).then(function(t){E[e]=t,f(e,t),n&&"from"===e&&f("to",t)}).catch(function(t){return E[e]={},s.handleError(t)}).finally(function(){s.uiOptions.times[e].loading=!1,n&&(s.uiOptions.times.to.loading=!1)}):r.resolve()}function D(t){var n=s.uiOptions.times[t];s["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0"}function R(t,n){var a="request"+e.startCase(t)+"DayTypes";s[a]=n,s.isMode("create")&&(s.request[t+"_date_type"]=s[a][0].value)}function S(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?(s.disableAndShowLoadingTimeInput("from"),!s.uiOptions.multipleDays&&s.disableAndShowLoadingTimeInput("to"),P("from").then(function(){T("from",!0)})):r.resolve()}function T(e,t){var n=s.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,i=n.multipleDays&&"from"===a?r.max:n.times.to.time,u=E[a].number_of_hours?h(o,i).toString():"0";r.maxAmount=u,t&&(r.amount=r.maxAmount)}function O(){var e=s.uiOptions.times;s.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,s.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function I(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?P("from").then(function(){T("from",!0)}):r.resolve()}var E={};a.debug("RequestModalDetailsLeaveController"),s.calculateBalanceChange=c,s.canCalculateChange=l,s.canSubmit=d,s.initChildController=g,s.initDayTypesExtended=b,s.initTimesExtended=q,s.initWatchersExtended=$,s.onAbsenceTypeUpdateExtended=I,s.onDateChangeExtended=w,s.resetUIInputsExtended=D,s.setDaysSelectionModeExtended=S}n.controller("RequestModalDetailsLeaveController",a),a.$inject=["$controller","$log","$q","$rootScope","detailsController","PublicHoliday","LeaveRequest"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s,i){function u(){return!(!i.canCalculateChange()||!i.request.sickness_reason)}function c(){return a.all([f(),h(),m(!0)])}function l(t){var n=i.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function d(t){return!!e.find(i.sicknessDocumentTypes,function(e){return e.value===t})}function f(){return s.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){i.sicknessDocumentTypes=e})}function m(t){return s.valuesOf("hrleaveandabsences_sickness_reason",t).then(function(t){i.sicknessReasons=e.indexBy(t,"name")})}function p(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1").on("crmUnload",function(){m(!1)})}function h(){i.showSicknessOptionsEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:i}),i.canSubmit=u,i.initChildController=c,i.isChecked=l,i.isDocumentInRequest=d,i.openSicknessReasonOptionsEditor=p}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","$rootScope","crmAngService","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return u.balance.change.amount=+u.request.toil_to_accrue,a.resolve(u.balance.change)}function l(){if(!u.request.from_date||!u.request.to_date)return u.uiOptions.max_toil_duration_and_accrual=null,void(u.uiOptions.toil_duration_in_hours=null);u.uiOptions.max_toil_duration_and_accrual=t.duration(t(u.request.to_date).diff(u.request.from_date)).asHours()}function d(){return v().catch(function(e){return e.length&&(u.errors=e),a.reject(e)}).then(function(e){return i.calculateToilExpiryDate(u.request.type_id,e)}).then(function(e){return u.request.toil_expiry_date=e,u.uiOptions.expiryDate=new Date(e),e})}function f(){return!!u.request.toil_to_accrue}function m(){var e=u.uiOptions.multipleDays&&!!u.request.to_date,t=!u.uiOptions.multipleDays&&!!u.request.from_date,n=t||e,a=F.from_date!==u.request.from_date||F.to_date!==u.request.to_date;return u.canDisplayToilExpirationField&&n&&H.hasExpirationFromAdminSettings&&a}function p(){return!!(u.request.from_date&&u.request.to_date&&u.request.toil_duration&&u.request.toil_to_accrue)}function h(){u.request.toil_expiry_date=!1,u.uiOptions.expiryDate=null}function v(){var e=u.uiOptions.multipleDays,t=u.request;return g({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function g(e){if(e.hasErrors){var n="Please select "+e.label+" to find expiry date";return a.reject([n])}return e.value?a.resolve(t(e.value).format("YYYY-MM-DD")):a.reject([])}function b(){var e=u.isMode("create")&&H.hasExpirationFromAdminSettings,t=H.hasPreviousExpirationDate,n=u.isLeaveType("toil"),a=u.canManage;u.canDisplayToilExpirationField=n&&(a||e||t)}function y(){u.uiOptions.toil_duration_in_hours=u.request.toil_duration/60}function _(){return H.hasPreviousExpirationDate=u.isMode("edit")&&!!u.request.toil_expiry_date,i.canExpire(u.request.type_id).then(function(e){H.hasExpirationFromAdminSettings=e})}function q(){return u.request.to_date_type=u.request.from_date_type="1",_().then(b).then($).then(R)}function $(){u.canManage&&(u.uiOptions.expiryDate=u.convertDateFormatFromServer(u.request.toil_expiry_date))}function C(){r.$watch(function(){return u.request.toil_to_accrue},function(e,t){+e!=+t&&u.performBalanceChangeCalculation()})}function A(){r.$watch(function(){return u.uiOptions.toil_duration_in_hours},function(e,t){ +e!==t&&u.isCalculationUnit("hours")&&I(),u.request.toil_duration=u.uiOptions.toil_duration_in_hours?60*u.uiOptions.toil_duration_in_hours:null})}function w(){var e=u.uiOptions.times;e.from.time=t(u.request.from_date).format("HH:mm"),e.to.time=t(u.request.to_date).format("HH:mm"),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time)}function P(){["from","to"].forEach(function(e){r.$watch(function(){return u.uiOptions.times[e].time},function(e,t){e!==t&&(u.setRequestDateTimesAndDateTypes(),B(),l(),E())})})}function D(){u.isMode("view")||(C(),A(),P())}function R(t){return s.valuesOf("hrleaveandabsences_toil_amounts",t).then(function(t){u.toilAmounts=e.sortBy(t,function(e){return+e.weight})})}function S(){return l(),E(),B()}function T(){return M(),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time),l(),U?U=!1:E(),B()}function O(e){u.uiOptions.times[e].time=""}function I(){u.request.toil_to_accrue=u.uiOptions.toil_duration_in_hours}function E(){u.uiOptions.toil_duration_in_hours=u.uiOptions.max_toil_duration_and_accrual}function x(){F=e.cloneDeep(u.request.attributes())}function M(){u.uiOptions.multipleDays?["from","to"].forEach(function(e){u.uiOptions.times[e].min="00:00",u.uiOptions.times[e].max="23:45"}):(u.uiOptions.times.from.min="00:00",u.uiOptions.times.from.max="23:30",u.uiOptions.times.to.min="00:15",u.uiOptions.times.to.max="23:45")}function L(){u.setRequestDateTimesAndDateTypes(),l(),E(),u.isCalculationUnit("hours")?I():u.request.toil_to_accrue=null}function k(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1").on("crmUnload",function(){R(!1)})}function j(){u.showTOILAccrualsOptionEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}function B(){return m()?d().catch(a.resolve):a.resolve()}function N(){u.uiOptions.expiryDate&&(u.request.toil_expiry_date=u.convertDateToServerFormat(u.uiOptions.expiryDate))}n.debug("RequestModalDetailsToilController");var F,U=!u.isMode("create"),H={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};u.canDisplayToilExpirationField=!1,u.calculateBalanceChange=c,u.canCalculateChange=f,u.canSubmit=p,u.clearExpiryDate=h,u.initChildController=q,u.initTimesExtended=w,u.initWatchersExtended=D,u.onAbsenceTypeUpdateExtended=L,u.onDateChangeExtended=S,u.openToilInDaysAccrualOptionsEditor=k,u.resetUIInputsExtended=O,u.setDaysSelectionModeExtended=T,u.updateExpiryDate=N,function(){x(),M(),j(),!u.isMode("create")&&y()}()}n.controller("RequestModalDetailsToilController",a),a.$inject=["$log","$q","$rootScope","crmAngService","OptionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/absence-period.instance",["leave-absences/shared/modules/models-instances","common/moment","common/models/instances/instance","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriodInstance",["$log","ModelInstance","HR_settings",function(e,n,a){return e.debug("AbsencePeriodInstance"),n.extend({defaultCustomData:function(){return{current:!1}},transformAttributes:function(e){var n=t();return e.current=!1,t(e.start_date).isSameOrBefore(n,"day")&&t(e.end_date).isSameOrAfter(n,"day")&&(e.current=!0),e},isInPeriod:function(e){var n=a.DATE_FORMAT.toUpperCase(),r=t(e,n);return t(this.start_date).isSameOrBefore(r)&&t(this.end_date).isSameOrAfter(r)}})}])}),define("leave-absences/shared/apis/absence-period.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("AbsencePeriodAPI",["$log","api",function(e,t){return e.debug("AbsencePeriodAPI"),t.extend({all:function(t){return e.debug("AbsencePeriodAPI"),this.sendGET("AbsencePeriod","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/models/absence-period.model",["leave-absences/shared/modules/models","common/moment","leave-absences/shared/modules/shared-settings","leave-absences/shared/instances/absence-period.instance","leave-absences/shared/apis/absence-period.api","common/models/model","common/services/hr-settings"],function(e,t){"use strict";e.factory("AbsencePeriod",["$log","Model","AbsencePeriodAPI","AbsencePeriodInstance","shared-settings",function(e,n,a,r,o){return e.debug("AbsencePeriod"),n.extend({all:function(e){return a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},current:function(){var e=t().format(o.serverDateFormat),n={start_date:{"<=":e},end_date:{">=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function f(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function m(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,m(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,m(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),f.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={from_date_amount:0,to_date_amount:0,request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,f,m,p,h,v,g,b,y,_,q,$,C){function A(e){"days"===Me.selectedAbsenceType.calculation_unit_name?delete Me.request[e+"_date_amount"]:delete Me.request[e+"_date_type"]}function w(){["from","to"].forEach(A)}function P(){var e=Me.requestStatuses[_.statusNames.awaitingApproval].value;Se.status_id===e&&e!==Me.request.status_id&&d.publish("ManagerBadge:: Update Count")}function D(){return xe.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function R(){return xe.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return!Me.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function T(){var e=D();return Me.isMode("edit")&&(e=e&&(V()||R())),Me.canManage&&Me.requestStatuses&&(e=e&&!!Me.getStatusFromValue(Me.newStatusOnSave)),(e=e&&!!Me.period.id)&&!Me.isMode("view")}function O(){Me.isSelfRecord?Me.request.status_id=Me.requestStatuses[_.statusNames.awaitingApproval].value:Me.canManage&&(Me.request.status_id=Me.newStatusOnSave||Me.request.status_id)}function I(){if(Me.isMode("edit")&&!Me.isRole("staff")&&"toil"!==F())return Me.request.calculateBalanceChange(Me.selectedAbsenceType.calculation_unit_name).then(function(e){if(+Me.balance.change.amount!=+e.amount)return C.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function E(){Me.errors=[]}function x(){return Me.request.create().then($e).then(function(){me("LeaveRequest::new")})}function M(){ee()&&!Me.isRole("staff")&&(Me.request.change_balance=!0)}function L(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return Me.request.delete().then(function(){Me.dismissModal(),d.publish("LeaveRequest::delete",Me.request)})}})}function k(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(Me.getStatusFromValue(Me.request.status_id).name)}function N(e){return n.map(De[e],function(e){return Me.requestStatuses[e]})}function F(){return Me.request?Me.request.request_type:Me.leaveType||null}function U(){return!Me.request||e.equals({},Me.requestStatuses)?[]:Me.request.status_id?B():N("none")}function H(e){return n.find(Me.requestStatuses,function(t){return t.value===e})}function W(e){Me.errors=n.isArray(e)?e:[e],Me.loading.absenceTypes=!1,Me.submitting=!1}function V(){return!e.equals(Se,Me.request.attributes())||Me.canManage&&Me.newStatusOnSave}function G(){return Me.postContactSelection=!0,Me.staffMemberSelectionComplete=!1,Me.request.contact_id?r.resolve().then(ie).then(ue).then(he).then(ge).then(Z).then(z).then(Me.isMode("edit")?be:n.noop).then(function(){Me.postContactSelection=!1,Me.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Ie)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];De.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],De.awaiting_approval=e,De.more_information_required=e,De.rejected=e,De.approved=e,De.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return Me.canManage?m.find(Me.request.contact_id).then(function(e){Me.contactName=e.display_name}):r.resolve()}function X(){Te.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(he).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",Me.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){W(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){Re++})),s.$on("$destroy",Ce),s.$on("LeaveRequestPopup::addTab",function(e,t){xe.push(t)})}function J(){var e,t;Me.request=Me.leaveRequest||null,e=F(),t=Me.initRequestAttributes(),"leave"===e?Me.request=y.init(t):"sickness"===e?Me.request=q.init(t):"toil"===e&&(Me.request=$.init(t))}function K(){var e={};return Me.request?e=Me.request.attributes():Me.canManage||(e={contact_id:Oe}),e}function Q(){if(Ee="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(Ee="admin")}).then(function(){return"staff"===Ee&&u(_.permissions.ssp.manage).then(function(e){e&&(Ee="manager")})}).finally(function(){Me.canManage=Me.isRole("manager")||Me.isRole("admin")})}function Z(){(Me.isRole("admin")||Me.isMode("create")&&Me.isRole("manager"))&&(Me.newStatusOnSave=Me.requestStatuses[_.statusNames.approved].value)}function ee(){return!Me.request.status_id||!n.includes(["cancelled","rejected"],H(Me.request.status_id).name)}function te(e){var t=Me.getStatusFromValue(Me.request.status_id);return!!t&&t.name===e}function ne(e){return Me.request&&Me.request.request_type===e}function ae(e){return Me.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date,"day")&&r.isSameOrBefore(t.end_date,"day")}function oe(e){return Ee===e}function se(){return h.all().then(function(e){Me.absencePeriods=e})}function ie(){return v.all(j()).then(v.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return Me.loading.entitlements=!0,g.all({contact_id:Me.request.contact_id,period_id:Me.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){Me.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Oe=e.contactId})}function le(){return Me.selectedContactId?m.find(Me.selectedContactId).then(function(e){Me.managedContacts=[e]}):Me.isRole("admin")?m.all().then(function(e){Me.managedContacts=n.remove(e.list,function(e){return e.id!==Oe})}):m.find(Oe).then(function(e){return e.leaveManagees()}).then(function(e){Me.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){Me.requestStatuses=n.indexBy(e,"name")})}function fe(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function me(e){P(),d.publish(e,Me.request),Me.errors=[],Me.dismissModal()}function pe(){["from","to"].forEach(function(e){Me.request[e+"_date"]=Se[e+"_date"]})}function he(e){if(Me.absenceTypes=fe(Pe.types,e),!Me.absenceTypes.length)return r.reject(Ie)}function ve(){Me.period=n.find(Me.absencePeriods,function(e){return Me.isMode("create")?e.current:re(Me.request,e)})}function ge(){Me.isMode("create")?(Me.selectedAbsenceType=Me.absenceTypes[0],Me.request.type_id=Me.selectedAbsenceType.id):Me.selectedAbsenceType=n.find(Me.absenceTypes,function(e){return e.id===Me.request.type_id})}function be(){Se=e.copy(Me.request.attributes())}function ye(){var e;Me.request.id?(e=[Me.requestStatuses[_.statusNames.approved].value,Me.requestStatuses[_.statusNames.adminApproved].value,Me.requestStatuses[_.statusNames.rejected].value,Me.requestStatuses[_.statusNames.cancelled].value],Me.mode="edit",Me.isRole("staff")&&e.indexOf(Me.request.status_id)>-1&&(Me.mode="view")):Me.mode="create"}function _e(){var e=Me.request.status_id;if(!Me.isMode("view")&&!Me.submitting)return Me.submitting=!0,O(),w(),Me.request.isValid().then(ee()&&I).then(M).then(!Me.request.change_balance&&pe).then(qe).then(function(){return Me.isMode("edit")?we():x()}).catch(function(t){Me.request.status_id=e,t&&W(t)}).finally(function(){Me.submitting=!1})}function qe(){return r.all(xe.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===Re&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return Re>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function Ce(){Te.forEach(function(e){e()})}function Ae(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function we(){return Me.request.update().then($e).then(function(){Me.isRole("manager")?me("LeaveRequest::updatedByManager"):(Me.isRole("staff")||Me.isRole("admin"))&&me("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,De={},Re=0,Se={},Te=[],Oe="",Ie="No entitlement",Ee="",xe=[],Me=n.assign(this,f);Me.absencePeriods=[],Me.absenceTypes=[],Me.canManage=!1,Me.contactName=null,Me.errors=[],Me.loading={absenceTypes:!0,entitlements:!0},Me.managedContacts=[],Me.mode="",Me.newStatusOnSave=null,Me.period={},Me.postContactSelection=!1,Me.requestStatuses={},Me.selectedAbsenceType={},Me.staffMemberSelectionComplete=!1,Me.submitting=!1,Me.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},Me.canChangeAbsenceType=S,Me.canSubmit=T,Me.closeAlert=E,Me.deleteLeaveRequest=L,Me.dismissModal=k,Me.getStatuses=U,Me.getStatusFromValue=H,Me.initAfterContactSelection=G,Me.initRequestAttributes=K,Me.isLeaveStatus=te,Me.isLeaveType=ne,Me.isMode=ae,Me.isRole=oe,Me.submit=_e,Me.updateAbsenceType=Ae,function(){Me.loading.absenceTypes=!0,Y(),X(),r.all([ce(),Q(),se(),de()]).then(J).then(ye).then(ve).then(function(){return Me.canManage&&!Me.isMode("edit")&&le()}).then(function(){if(Me.selectedContactId&&(Me.request.contact_id=Me.selectedContactId),Me.request.contact_id)return Me.initAfterContactSelection()}).catch(W).finally(function(){Me.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n, +leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),function(e){define("leave-absences/admin-dashboard/modules/settings",["common/angular"],function(t){return t.module("admin-dashboard.settings",[]).constant("settings",{contactId:e.vars.leaveAndAbsences.loggedInUserId,debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/admin-dashboard/"})})}(CRM),define("leave-absences/admin-dashboard/modules/config",["common/angular","leave-absences/admin-dashboard/modules/settings"],function(e){return e.module("admin-dashboard.config",["admin-dashboard.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(e,t,n,a,r,o){var s={format:["DateFormat",function(e){return e.getDateFormat()}]};r.debugEnabled(o.debug),t.defaults.stripTrailingSlashes=!1,a.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",n.otherwise("/requests"),e.state("requests",{url:"/requests",template:'',resolve:s}).state("calendar",{url:"/calendar",template:'',resolve:s}).state("leave-balances",{url:"/leave-balances",template:"",resolve:s})}])}),define("leave-absences/admin-dashboard/modules/components",["common/angular"],function(e){return e.module("admin-dashboard.components",[])}),define("leave-absences/admin-dashboard/components/admin-dashboard-container",["leave-absences/admin-dashboard/modules/components"],function(e){function t(e,t){e.debug("Component: admin-dashboard-container"),t.section="admin-dashboard"}e.component("adminDashboardContainer",{templateUrl:["settings",function(e){return e.pathTpl+"components/admin-dashboard-container.html"}],controllerAs:"vm",controller:["$log","$rootScope",t]})}),define("leave-absences/admin-dashboard/app",["common/angular","common/angularBootstrap","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/services/check-permissions","common/services/crm-ang.service","common/services/angular-date/date-format","leave-absences/shared/ui-router","leave-absences/shared/components/leave-balance-tab.component","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/manage-leave-requests.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/admin-dashboard/modules/config","leave-absences/admin-dashboard/components/admin-dashboard-container"],function(e){return e.module("admin-dashboard",["ngAnimate","ngResource","ui.bootstrap","ui.router","ui.select","textAngular","common.angularDate","common.dialog","common.filters","common.mocks","leave-absences.components","leave-absences.controllers","leave-absences.settings","leave-absences.services","admin-dashboard.config","admin-dashboard.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/admin-dashboard":n+"/admin-dashboard"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/admin-dashboard/app"],function(){document.dispatchEvent("function"==typeof window.CustomEvent?new CustomEvent("adminDashboardReady"):function(){var e=document.createEvent("Event");return e.initEvent("adminDashboardReady",!0,!0),e}())})})}(CRM,require),define("admin-dashboard",function(){}); //# sourceMappingURL=/sites/all/modules/civicrm/tools/extensions/civihr/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/admin-dashboard.js.map \ No newline at end of file diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/manager-leave.min.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/manager-leave.min.js index 6ec92696a82..41ef803e7b1 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/manager-leave.min.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/manager-leave.min.js @@ -6,9 +6,9 @@ */ -!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return W(new(W(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[f]),c[r[f]]=e[r[f]]);return W({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))h.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&m(u[e],e)}),h.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var v=s(u||{}),h=[],g=[],b={};return H(u,m),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),m.$$values=b,m.$$promises=m.$$promises||!0,delete m.$$inheritedValues,c.resolve(b))}function u(e){m.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),m=c.promise,g=m.$$promises={},b=W({},a),y=1+h.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),m;o.$$inheritedValues&&r(b,f(o.$$inheritedValues,v)),W(g,o.$$promises),o.$$values?(_=r(b,f(o.$$values,v)),m.$$inheritedValues=f(o.$$values,v),i()):(o.$$inheritedValues&&(m.$$inheritedValues=f(o.$$inheritedValues,v)),o.then(i,u));for(var q=0,$=h.length;q<$;q+=3)a.hasOwnProperty(h[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(m.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),f=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(f++,g[e].then(function(t){b[e]=t,--f||l()},c))}),f||l(),g[n]=d.promise}(h[q],h[q+1],h[q+2]);return m}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(h.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(v[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return v[t]=new Y.Param(t,n,a,r),v[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(f,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=W({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",f=0,m=this.segments=[],p=r?r.params:{},v=this.params=r?r.params.$$new():new Y.ParamSet,h=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),m.push(g.segment),f=c.lastIndex;y=e.substring(f);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,f+_),q.length>0)for(f=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),f=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",m.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=m[0],this.$$paramNames=h}function y(e){W(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:v,caseInsensitive:f}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){W(this,e||{})}Y=this;var d,f=!1,v=!0,h=!1,g={},q=!0,$=[],C={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(f=e),f},this.strictMode=function(e){return j(e)&&(v=e),v},this.defaultSquashPolicy=function(e){if(!j(e))return h;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return h=e,e},this.compile=function(e,t){return new b(e,W(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(W({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(C,function(e,t){g[t]=new y(W({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(C,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!v.type.is(e))throw new Error("Default value ("+e+") for parameter '"+v.id+"' is not an instance of Type ("+v.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(m(v.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?v.type.$normalize(e):c()}function f(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var v=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return W(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return h;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),m(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);W(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:f})},l.prototype={$$new:function(){return a(this,W(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return m(r,t.self);for(var o in S)B(S[o])&&(t[o]=S[o](t,S.$delegates[o]));return P[n]=t,!t[D]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){w.$current.navigable==t&&c(e,n)||w.transitionTo(t,e,{inherit:!0,location:!1})}]),h(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=w.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=M[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(w.$current=t,w.current=t.self,w.params=n,V(w.params,m),w.transition=null,o.location&&t.navigable&&h.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),h.update(!0),w.current)}).then(null,function(a){return a===R?S:w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(w.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||h.update(),r.reject(a))});return B},w.is=function(e,t,a){a=W({relative:w.$current},a||{});var r=f(e,a.relative);return j(r)?w.$current===r&&(!t||c(r.params.$$values(t),m)):n},w.includes=function(e,t,a){if(a=W({relative:w.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=w.$current.name}var r=f(e,a.relative);if(!j(r))return n;if(!j(w.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(f&&(f.remove(),f=null),p&&(p.$destroy(),p=null),m){var e=m.data("$uiViewAnim");b.leave(m,function(){e.$$animLeave.resolve(),f=null}),f=m,m=null}}function d(s){var d,f=R(n,c,i,r),y=f&&e.$current&&e.$current.locals[f];if(s||y!==v){d=n.$new(),v=e.$current.locals[f],d.$emit("$viewContentLoading",f);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});m=_,p=d,p.$emit("$viewContentLoaded",f),p.$eval(h)}}var f,m,p,v,h=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=R(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var f=t.extend({},d);o[d.$$resolveAs]=f;var m=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=f),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}m(o)}}}}}function R(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function D(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function S(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function T(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function I(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function O(e,t){return{relative:S(e)||t.$current,inherit:!0}}function L(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=D(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=T(r),d=s[1]||s[0],f=null;c.options=W(O(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var m=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),f&&f(),d&&(f=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&m(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),m(),l.clickable&&(i=I(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function M(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){f.state=t[0],f.params=t[1],f.options=t[2],f.href=e.href(f.state,f.params,f.options),m&&m(),c&&(m=c.$$addStateInfo(f.state,f.params)),f.href&&r.$set(u.attr,f.href)}var i,u=T(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",f={state:null,params:null,options:null,href:null},m=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=I(a,e,t,u,function(){return f}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function k(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,S(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return v.push(u),h[s]=r,function(){var e=v.indexOf(u);-1!==e&&v.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function x(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function E(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,W=t.extend,V=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),h.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",h),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,W(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;a=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/components/leave-balance-tab-filters.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n){function a(e){e.absencePeriods&&c.absencePeriods.length&&(c.filters.period_id=o().id),e.absenceTypes&&c.absenceTypes.length&&(c.filters.type_id=s().id),(e.loggedInContactId||e.userRole)&&(c.filters.managed_by="manager"===c.userRole?c.loggedInContactId:void 0),r()&&c.submitFilters()}function r(){return e.every(c.filters,function(e){return null!==e})}function o(){return e.find(c.absencePeriods,function(e){return e.current})||c.absencePeriods.reduce(function(e,n){return t(e.end_date).isAfter(n.end_date)?e:n})}function s(){return c.absenceTypes.reduce(function(e,t){return e.title.localeCompare(t.title)?e:t})}function i(e){return e.current?"Current Period ("+e.title+")":e.title}function u(){n.$emit("LeaveBalanceFilters::update",c.filters)}var c=this;c.filters={period_id:null,type_id:null,managed_by:null},c.$onChanges=a,c.labelPeriod=i,c.submitFilters=u}n.component("leaveBalanceTabFilters",{controller:a,controllerAs:"balanceFilters",bindings:{absencePeriods:"<",absenceTypes:"<",loggedInContactId:"<",lookupContacts:"<",userRole:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-balance-tab-filters.html"}]}),a.$inject=["$scope"]}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,n){function a(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(n.remainder=a[0].remainder),delete n["api.LeavePeriodEntitlement.getremainder"],n}function r(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return n.value=a,delete n["api.LeavePeriodEntitlement.getentitlement"],n}return e.debug("EntitlementAPI"),n.extend({all:function(t,n){return e.debug("EntitlementAPI.all"),t["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},n&&(t["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",t,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r),n&&(e=e.map(a)),e})},breakdown:function(t){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",t).then(function(e){return e.values})},getLeaveBalances:function(t,n,a,r,o){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",t,n,a,r,"getLeaveBalances",o)}})}])}),define("leave-absences/shared/models/leave-balance-report.model",["leave-absences/shared/modules/models","leave-absences/shared/apis/entitlement.api","common/models/model"],function(e){"use strict";e.factory("LeaveBalanceReport",["Model","EntitlementAPI",function(e,t){return e.extend({all:function(e,n,a,r,o){return t.getLeaveBalances(this.processFilters(e),n,a,r,o)}})}])}),define("leave-absences/shared/components/leave-balance-tab.component",["common/angular","common/lodash","leave-absences/shared/modules/components","leave-absences/shared/components/leave-balance-tab-filters.component","leave-absences/shared/models/leave-balance-report.model","common/services/notification.service","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f){function m(){return r.all({options:{sort:"title ASC"}}).then(function(e){P.absencePeriods=e})}function p(){return o.all().then(o.loadCalculationUnits).then(function(e){P.absenceTypes=e})}function v(){return s.all(null,null,"sort_name ASC").then(function(e){P.lookupContacts=e.list})}function h(){return n.all([m(),p(),v(),g(),q()]).catch(function(e){u.error("Error",e)})}function g(){return l.get().then(function(e){P.loggedInContactId=e.contactId})}function b(){return P.loading.report=!0,i.all(w,P.pagination,void 0,void 0,!1).then(function(e){P.report=y(e.list),P.reportCount=e.total}).catch(function(e){u.error("Error",e.error_message)}).finally(function(){P.loading.report=!1})}function y(n){return n.map(function(n){return n=e.copy(n),n.absence_types=t.indexBy(n.absence_types,function(e){return e.id}),n})}function _(){a.$on("LeaveBalanceFilters::update",C),c.subscribe("LeaveRequest::new",$)}function q(){return f(d.permissions.admin.administer).then(function(e){P.userRole=e?"admin":"manager"})}function $(e){C(e,w)}function C(e,t){w=t,P.pagination.page=1,A(),P.loadReportCurrentPage()}function A(){P.selectedAbsenceTypes=P.absenceTypes.filter(function(e){return+e.id==+w.type_id})}var w={},P=this;P.absencePeriods=[],P.absenceTypes=[],P.loading={component:!0,report:!0},P.loggedInContactId=null,P.lookupContacts=[],P.pagination={page:1,size:50},P.report=[],P.reportCount=0,P.userRole=null,P.loadReportCurrentPage=b,function(){_(),h().then(function(){P.loading.component=!1})}()}n.component("leaveBalanceTab",{controller:a,controllerAs:"leaveBalanceTab",templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-balance-tab.html"}]}),a.$inject=["$q","$rootScope","AbsencePeriod","AbsenceType","Contact","LeaveBalanceReport","notificationService","pubSub","Session","shared-settings","checkPermissions"]}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,t,n){function a(n,a,r,o,s,i){function u(){return d().then(function(n){var a=n.filter(function(e){var n=e.info.details;return t(n.period_start_date).isSameOrBefore(h.selectedPeriod.end_date)&&(t(n.period_end_date).isSameOrAfter(h.selectedPeriod.start_date)||!n.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function c(){return{loadContacts:function(){var e=h.filters.userSettings.assignedTo.type;return f(e).then(function(e){h.lookupContacts=e}).then(function(){return"me"!==e?u():a.resolve(null)}).then(function(e){return h.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return r.all(m(),null,"display_name").then(function(e){return e.list})}function d(){return v?a.resolve(v):s.all()}function f(e){return"me"===e?r.leaveManagees(h.contactId):"unassigned"===e?r.leaveManagees(void 0,{unassigned:!0}):r.all().then(function(e){return e.list})}function m(){return{department:h.filters.userSettings.department?h.filters.userSettings.department.value:null,level_type:h.filters.userSettings.level_type?h.filters.userSettings.level_type.value:null,location:h.filters.userSettings.location?h.filters.userSettings.location.value:null,region:h.filters.userSettings.region?h.filters.userSettings.region.value:null,id:{IN:h.filters.userSettings.contact?[h.filters.userSettings.contact.id]:h.lookupContacts.map(function(e){return e.id})}}}function p(e){i.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var v,h;return{init:function(e){return h=e,h.showContactDetailsLink=!0,h.showContactName=!0,h.showFilters=!0,h.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],h.filters.userSettings.assignedTo=h.filtersByAssignee[0],h.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,f){function m(){for(var e=[],t=n(M.selectedPeriod.start_date).clone().startOf("month"),a=n(M.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");M.months=e}function p(){s.$new().$watch(function(){return M.selectedMonths},function(t,n){null===n||e.equals(t,n)||D()})}function v(e){M.injectMonths=!0,I("injected").then(function(){D(e)}).then(function(){M.loading.calendar=!1})}function h(){O=a("LeaveCalendar"+t.capitalize(L)+"Controller").init(M)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){M.absencePeriods=t.sortBy(e,"start_date"),M.selectedPeriod=t.find(M.absencePeriods,function(e){return!!e.current})}).then(m).then(S)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return O.loadContacts().then(function(e){M.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){M.filters.optionValues.regions=e.hrjc_region,M.filters.optionValues.locations=e.hrjc_location,M.filters.optionValues.levelTypes=e.hrjc_level_type,M.filters.optionValues.departments=e.hrjc_department})}function C(){return l.all()}function A(){return r.all([y(),C(),_()]).then(function(e){M.supportData.absenceTypes=e[0],M.supportData.publicHolidays=e[1],M.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,M.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,M.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,M.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function w(){var e=r.resolve();return M.injectMonths&&(e=I("destroyed"),M.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function R(e){e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){M.loading.calendar=!0}).then(w).then("period"===e?m:t.noop).then("contacts"===e?q:t.noop).then(function(){v("contacts"===e)})}function D(e){var n=M.selectedMonths.length?M.months.filter(function(e){return t.includes(M.selectedMonths,e.index)}):M.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function S(){M.selectedMonths=[n().month()]}function T(){return M.roleOverride?r.resolve().then(function(){L=M.roleOverride}):r.all([f(i.permissions.admin.administer),f(i.permissions.ssp.manage)]).then(function(e){L=e[0]?"admin":e[1]?"manager":"staff"})}function I(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===M.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var O,L,M=this;M.absencePeriods=[],M.contacts=[],M.contactIdsToReduceTo=null,M.injectMonths=!1,M.months=[],M.selectedMonths=null,M.selectedPeriod=null,M.showContactName=!1,M.showFilters=!1,M.supportData={},M.loading={calendar:!0,page:!0},M.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},M.labelPeriod=g,M.refresh=R,function(){T().then(p).then(h).then(w).then(b).then(function(){return r.all([q(),A()])}).then(function(){return M.showFilters?$():t.noop}).then(function(){v()}).then(function(){M.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r){"use strict";function o(){_.calculationUnit=s(_.supportData.calculationUnits,"value",g.calculation_unit)}function s(t,n,a){return e.find(t,function(e){return+e[n]==+a})}function i(){var e,n;return n=t(_.contactData.leaveRequest.from_date).isSame(_.contactData.leaveRequest.to_date,"day"),e=n?"single-date":"multiple-dates","type-"+_.calculationUnit.name+"-on-"+e+"-tooltip"}function u(){g=s(_.supportData.absenceTypes,"id",_.contactData.leaveRequest.type_id),_.contactData.leaveRequest["type_id.title"]=g.title}function c(){"days"===_.calculationUnit.name&&(b=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.from_date_type),y=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.to_date_type),_.contactData.leaveRequest["from_date_type.label"]=b.label,_.contactData.leaveRequest["to_date_type.label"]=y.label)}function l(e,t,n,a,o){e.stopPropagation(),r.openModal(t,n,a,o)}function d(){_.dates.from=new Date(_.contactData.leaveRequest.from_date),_.dates.to=new Date(_.contactData.leaveRequest.to_date)}function f(){_.contactData.isAccruedTOIL?_.label="AT":"days"===_.calculationUnit.name?m():p()}function m(){_.label=_.contactData.isAM?"AM":_.contactData.isPM?"PM":""}function p(){var e=t(_.contactData.leaveRequest.from_date).isSame(_.date,"day"),n=t(_.contactData.leaveRequest.to_date).isSame(_.date,"day");_.label=e?t(_.contactData.leaveRequest.from_date).format("HH:mm"):n?t(_.contactData.leaveRequest.to_date).format("HH:mm"):""}function v(){_.tooltipTemplate=_.contactData.isAccruedTOIL?"accrued-toil-tooltip":i()}function h(){a.$watch("day.contactData.leaveRequest",function(){_.contactData&&_.contactData.leaveRequest&&(u(),o(),c(),f(),d(),v())})}n.debug("Component: leave-calendar-day");var g,b,y,_=this;_.calculationUnit="",_.dates={from:null,to:null},_.label="",_.tooltipTemplate=null,_.openLeavePopup=l,function(){h()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){y([e]),B(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(W.period.start_date)&&r.isSameOrBefore(W.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function f(e){return U[e]}function m(){return W.showOnlyWithLeaveRequests?W.contacts.filter(function(e){return Object.keys(H[e.id]||{}).length}):W.contacts}function p(e){return t(e,u.serverDateFormat)}function v(e){O(e),B(e)}function h(e){return CRM.url("civicrm/contact/view",{cid:e})}function g(){return W.contactIdsToReduceTo&&(W.contacts=W.contacts.filter(function(t){return e.includes(W.contactIdsToReduceTo,t.contact_id)||e.find(H,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function b(){W.supportData.dayTypes=e.indexBy(W.supportData.dayTypes,"name"),W.supportData.leaveRequestStatuses=e.indexBy(W.supportData.leaveRequestStatuses,"value"),W.supportData.publicHolidays=e.transform(W.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function y(e){return e.forEach(function(e){var t=w(e);H[e.contact_id]=H[e.contact_id]||{},t.forEach(function(t){H[e.contact_id][t.date]=e})}),a.resolve()}function _(){F.push(r.$on("LeaveCalendar::showMonths",x)),F.push(i.subscribe("LeaveRequest::new",c)),F.push(i.subscribe("LeaveRequest::edit",j)),F.push(i.subscribe("LeaveRequest::updatedByManager",j)),F.push(i.subscribe("LeaveRequest::delete",v)),F.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?v(e.leaveRequest):j(e.leaveRequest)}))}function q(e,n,a){var r=W.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function $(e,t){return e.request_type===t}function C(e){return!!W.supportData.publicHolidays[p(e).valueOf()]}function A(t){var n=W.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function w(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===W.month.index&&r.year()===W.month.year&&a.push(e.find(W.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function P(t){return e.find(H[t.contact_id],function(e){return t.id===e.id})}function R(t){var n=e.find(W.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function D(){return[R(u.statusNames.approved),R(u.statusNames.adminApproved),R(u.statusNames.awaitingApproval),R(u.statusNames.moreInformationRequired)]}function S(){return W.month.loading=!0,a.all([I(),T()]).then(g).then(k).then(function(){N=!0}).then(function(){W.month.loading=!1})}function T(){return s.all({from_date:{to:W.month.days[W.month.days.length-1].date},to_date:{from:W.month.days[0].date},status_id:{IN:D()},contact_id:{IN:W.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(W.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return y(e.list)})}function I(){var t=W.month.days[0].date,n=W.month.days[W.month.days.length-1].date;return o.get(W.contacts.map(function(e){return e.id}),t,n).then(function(t){U=e.indexBy(t,"contact_id")})}function O(t){H[t.contact_id]=e.omit(H[t.contact_id],function(e){return e.id===t.id})}function L(){r.$emit("LeaveCalendar::monthDestroyed"),F.map(function(e){e.remove?e.remove():e()})}function M(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=f(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:C(t.date)})}),o.then(function(){return H[n]?H[n][t.date]:null}).then(function(a){e.assign(t.contactsData[n],{leaveRequest:a||null,styles:a?E(a):null,isAccruedTOIL:a?$(a,"toil"):null,isRequested:a?A(a):null,isAM:a?q("half_day_am",a,t.date):null,isPM:a?q("half_day_pm",a,t.date):null})})}function k(){return a.all(W.month.days.map(function(e){return a.all(W.contacts.map(function(t){return M(e,t.id)}))}))}function x(t,n,a){!e.find(n,function(e){return e.index===W.month.index})?W.visible=!1:(W.currentPage=0,W.visible=!0,(a||!N)&&S())}function E(t){var n=e.find(W.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function j(e){var t=P(e);t&&(v(t),-1!==D().indexOf(e.status_id)&&c(e))}function B(e){return a.all(w(e).map(function(t){return M(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var N=!1,F=[],U={},H={},W=this;W.currentPage=0,W.pageSize=20,W.visible=!1,W.showContactName=!!W.showContactName,W.showOnlyWithLeaveRequests=!!W.showOnlyWithLeaveRequests,W.$onDestroy=L,W.contactsList=m,W.getContactUrl=h,function(){var e=t().month(W.month.index).year(W.month.year);b(),_(),W.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o,promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}), -define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(v(t)):m(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function f(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||!!e.includes([$.awaitingApproval,$.moreInformationRequired],n)&&("manager"===q.role||("3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a))}function m(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):v(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function v(e){var t=C[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function h(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(C,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!f(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:C[e].label,isDirectAction:C[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,C={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=h,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function f(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function m(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function v(e){return q.mode===e}function h(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=f,q.getActiveComments=m,q.getCommentorName=p,q.isMode=v,q.onBeforeSubmit=h,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f,m){function p(){pe.balance.closing=pe.balance.opening+pe.balance.change.amount}function v(e){return t(e,u.serverDateFormat).toDate()}function h(e){return t(e).format(u.serverDateFormat)}function g(e){var t;return s.resolve().then(function(){X(e),"from"===e&&K(),B("hours")&&(_(e),"from"!==e||pe.uiOptions.multipleDays||_("to")),pe.loading[e+"DayTypes"]=!0}).then(pe.onDateChangeExtended).then(function(){return C(e)}).then(function(e){if(t=e.id!==pe.period.id,t&&(pe.period=e),!pe.period.id)return s.reject("Please change date as it is not in any absence period")}).then(Z).then(function(){if(t)return V()}).then(function(){return U(pe.uiOptions[e+"Date"],e)}).then(function(){if(B("hours"))return W(e).then(function(){ne(e,!0)})}).then(function(){if(oe(),!t)return Y();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(S)}function b(){return oe(),Y()}function y(){return pe.uiOptions.toDate=null,X("to"),s.resolve().then(function(){if(B("hours")&&pe.uiOptions.fromDate)return _("from"),!pe.uiOptions.multipleDays&&_("to"),W("from").then(function(){ne("from",!0)}).then(oe)}).then(pe.setDaysSelectionModeExtended).then(!pe.uiOptions.multipleDays&&Y)}function _(e){var t=pe.uiOptions.times[e];t.loading=!0,t.disabled=!0}function q(t,n){var a=pe.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);pe.uiOptions.multipleDays||("from"===t&&o&&r&&(o=P(o).subtract(pe.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=P(r).add(pe.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min,a.disabled=!1}function $(t,n){return t?(t=h(t),d.isPublicHoliday(t).then(function(n){return n?pe.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):A(t,pe.requestDayTypes).then(function(t){return t.length?t:pe.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return te(n,e),e})):s.reject([])}function C(n){var a=t(pe.uiOptions[n+"Date"]).format(pe.uiOptions.userDateFormat.toUpperCase());return e.find(pe.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function A(e,n){return e=t(e),s.all([pe.calendar.isNonWorkingDay(e),pe.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function w(){return pe.request?pe.request.request_type:pe.leaveType||null}function P(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function R(){return ie(),pe.loading.balanceChange=!0,pe.request.getBalanceChangeBreakdown().then(Q).catch(S)}function D(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function S(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),pe.loading.fromDayTypes=!1,pe.loading.balanceChange=!1,pe.loading.tab=!1,pe.loading.toDayTypes=!1}function T(){return pe.isMode("create")||pe.forceRecalculateBalanceChange?Y():R()}function I(){var e=pe.request.attributes();return pe.uiOptions.fromDate=v(pe.request.from_date),U(pe.uiOptions.fromDate,"from").then(function(){return pe.request.to_date=e.to_date,pe.request.to_date_type=e.to_date_type,pe.uiOptions.toDate=v(pe.request.to_date),U(pe.uiOptions.toDate,"to")})}function O(e){o.$watch("detailsTab.uiOptions.times."+e+".amount",function(e,t){B("days")||+e==+t||(se(),pe.performBalanceChangeCalculation())})}function L(){me.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){ce()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){le(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",Y))}function M(){pe.isMode("edit")&&(pe.isLeaveStatus(u.statusNames.approved)||pe.isLeaveStatus(u.statusNames.adminApproved))&&(fe={absenceTypeId:pe.request.type_id,value:pe.selectedAbsenceType.remainder-pe.request.balance_change})}function k(e){var n=t(pe.request[e+"_date"]).format("HH:mm"),a=pe.uiOptions.times[e];(D(a.min,n)<=0||D(a.max,n)>=0)&&(n="from"===e?a.min:a.max),pe.uiOptions.times[e].time=n}function x(){var e=pe.uiOptions.multipleDays?["from","to"]:["from"],t=pe.uiOptions.times;return s.all(e.map(W)).then(function(){["from","to"].forEach(function(e){k(e),ne(e),t[e].amount=Math.min(pe.request[e+"_date_amount"],t[e].maxAmount).toString()}),pe.uiOptions.multipleDays||de(pe.uiOptions.times.from.time)}).then(se)}function E(){["from","to"].forEach(function(e){O(e),j(e)})}function j(e){o.$watch("detailsTab.uiOptions.times."+e+".time",function(t,n){B("days")||t===n||(oe(),t&&(!pe.uiOptions.multipleDays&&"from"===e&&de(t),ne(e,!0)))})}function B(e){return pe.selectedAbsenceType.calculation_unit_name===e}function N(e){return pe.request.request_type===e}function F(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function U(e,t){return $(e,t).then(function(){pe.loading[t+"DayTypes"]=!1})}function H(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){pe.requestDayTypes=e})}function W(e){var t=pe.uiOptions[e+"Date"],n=pe.uiOptions.times[e],a=!pe.uiOptions.multipleDays;return t?pe.request.getWorkDayForDate(h(t)).then(function(t){ve[e]=t,q(e,t),a&&"from"===e&&q("to",t)}).catch(function(t){return ve[e]={},S(t)}).finally(function(){n.loading=!1,a&&(pe.uiOptions.times.to.loading=!1)}):s.resolve()}function V(){return c.get(pe.request.contact_id,pe.period.start_date,pe.period.end_date).then(function(e){pe.calendar=e})}function G(){var e=(pe.pagination.currentPage-1)*pe.pagination.numPerPage,t=e+pe.pagination.numPerPage;pe.pagination.filteredbreakdown=pe.balance.change.breakdown.slice(e,t)}function Y(){return ie(),pe.canCalculateChange()?(pe.loading.balanceChange=!0,pe.request.change_balance=!0,pe.calculateBalanceChange().then(Q).catch(S).finally(function(){pe.loading.balanceChange=!1})):s.resolve()}function z(){pe.pagination.totalItems=pe.balance.change.breakdown.length,pe.pagination.filteredbreakdown=pe.balance.change.breakdown,pe.pagination.pageChanged()}function J(){return h(pe.request.from_date)===h(pe.request.to_date)}function K(){pe.uiOptions.toDate&&pe.uiOptions.fromDate&&pe.uiOptions.multipleDays&&t(pe.uiOptions.toDate).isSameOrBefore(pe.uiOptions.fromDate)&&(pe.uiOptions.toDate=null,X("to"))}function X(t){var n=pe.uiOptions.times[t];pe["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0",n.loading=!1,oe(),se(),ie()}function Q(e){pe.balance.change=e,pe.request.balance_change=e.amount,p(),z(),pe.loading.balanceChange=!1}function Z(){var e,n,a;pe.uiOptions.fromDate?(e=t(pe.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=v(pe.period.start_date),n=pe.uiOptions.date.to.options.minDate),pe.uiOptions.date.to.options.initDate=n,pe.uiOptions.date.to.options.minDate=a,pe.uiOptions.date.to.options.maxDate=v(pe.period.end_date)}function ee(){return!pe.isMode("create")&&J()||pe.isMode("create")&&(N("sickness")||B("hours"))?pe.uiOptions.multipleDays=!1:pe.uiOptions.multipleDays=!0,s.resolve().then(pe.setDaysSelectionModeExtended)}function te(t,n){var a="request"+e.startCase(t)+"DayTypes";pe[a]=n,pe.isMode("create")&&(pe.request[t+"_date_type"]=pe[a][0].value)}function ne(e,t){var n=pe.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,s=n.multipleDays&&"from"===a?r.max:n.times.to.time,i=ve[a].number_of_hours?D(o,s).toString():"0";r.maxAmount=i,t&&(r.amount=r.maxAmount)}function ae(){fe&&fe.absenceTypeId===pe.selectedAbsenceType.id?pe.balance.opening=fe.value||0:pe.balance.opening=pe.selectedAbsenceType.remainder}function re(){pe.selectedAbsenceType=e.find(pe.absenceTypes,function(e){return e.id===pe.request.type_id})}function oe(){var e=pe.uiOptions,t=e.times;pe.request.from_date=e.fromDate?h(e.fromDate):null,pe.request.to_date=e.toDate?h(e.toDate):null,!e.multipleDays&&e.fromDate&&(pe.request.to_date=pe.request.from_date,pe.request.to_date_type=pe.request.from_date_type),B("hours")&&!N("toil")&&(pe.request.from_date=pe.request.from_date&&t.from.time?pe.request.from_date+" "+t.from.time:null,pe.request.to_date=pe.request.to_date&&t.to.time?pe.request.to_date+" "+t.to.time:null)}function se(){var e=pe.uiOptions.times;pe.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,pe.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function ie(){pe.uiOptions.showBalance=pe.canCalculateChange()}function ue(){e.forEach(me,function(e){e()})}function ce(){var e,t=pe.selectedAbsenceType.calculation_unit_name;return re(),e=t!==pe.selectedAbsenceType.calculation_unit_name,ae(),s.resolve().then(e&&ee).then(function(){if(e&&B("hours"))return W("from").then(function(){ne("from",!0)})}).then(e&&oe).then(Y)}function le(e){return pe.absenceTypes=e,re(),t(pe.uiOptions.toDate).isAfter(pe.period.end_date)&&(pe.uiOptions.toDate=void 0,X("to")),ae(),Y()}function de(e){var t=P(e).add(pe.uiOptions.time_interval,"minutes");t.isAfter(P(pe.uiOptions.times.to.max))||(pe.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(P(pe.uiOptions.times.to.time))&&(pe.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var fe=null,me=[],pe=this,ve={};pe.canManage=!1,pe.calendar={},pe.errors=[],pe.isRequired=!0,pe.requestDayTypes=[],pe.statusNames=u.statusNames,pe.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},pe.pagination={currentPage:1,filteredbreakdown:pe.balance.change.breakdown,numPerPage:7,totalItems:pe.balance.change.breakdown.length,pageChanged:G},pe.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},pe.convertDateFormatFromServer=v,pe.convertDateToServerFormat=h,pe.dateChangeHandler=g,pe.dateTypeChangeHandler=b,pe.daysSelectionModeChangeHandler=y,pe.isLeaveType=N,pe.isNotWorkingDay=F,pe.performBalanceChangeCalculation=Y,pe.$onDestroy=ue,function(){n("RequestModalDetails"+e.capitalize(w(pe.leaveType,pe.request))+"Controller",{detailsController:pe}),pe.canManage=pe.isRole("manager")||pe.isRole("admin"),pe.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",pe),L(),pe.initChildController().then(function(){return s.all([V(),H()])}).then(!pe.isMode("create")&&I).then(ee).then(function(){if(!pe.isMode("create")&&B("hours"))return x().then(oe)}).then(!pe.isMode("create")&&Z).then(M).then(ae).then(T).then(function(){pe.isMode("view")||N("toil")||E()}).catch(S).finally(function(){pe.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","PublicHoliday","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return T.fileUploader&&T.fileUploader.queue.length>0}function f(){return T.getFilesAmount()0?R.map(function(e){return e.label}).join(", "):""}function q(){return T.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(R.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){S[e.label]=t})})).catch(function(){S=null})}function C(){return u.valuesOf("safe_file_extension").then(function(e){R=e})}function A(e){return!e.attachment_id||T.canManage}function w(){e.forEach(D,function(e){e()})}function P(e,t){T.fileUploader.queue&&T.fileUploader.queue.length>0?T.fileUploader.uploadAll({entityID:T.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var R=[],D=[],S={},T=Object.create(this);return T.filesLoaded=!1,T.fileUploader=null,T.today=Date.now(),T.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",T.userDateFormat=s.DATE_FORMAT,T.$onDestroy=w,T.canRemoveAttachment=A,T.canSubmit=d,T.canUploadMore=f,T.formatDateTime=m,T.getAuthorName=p,T.getFilesAmount=v,T.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",T),b(),a.all([C(),q()]).then(y).finally(function(){T.filesLoaded=!0})}(),T}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"},{type:"toil",icon:"calendar-plus-o",label:"Overtime"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{btnClass:"@",contactId:"<",selectedContactId:"<",isSelfRecord:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/manage-leave-requests.component",["common/lodash","leave-absences/shared/modules/components","common/models/contact","common/services/pub-sub"],function(e,t){function n(t,n,a,r,o,s,i,u,c,l,d,f){"use strict";function m(){U.filters.leaveRequest.contact_id=null,U.refresh()}function p(){var e=U.filters.contact;return{department:e.department,level_type:e.level_type,location:e.location,region:e.region}}function v(e){return"all"===e.name||""===e?U.leaveRequests.filter.list.length:U.leaveRequests.filter.list.filter(function(t){return t.status_id===e.value}).length}function h(t){return e.find(U.absenceTypes,{id:t})}function g(e){return new Array(e||0)}function b(t){var n=e.find(U.leaveRequestStatuses,function(e){return e.value===t});return n?n.label:null}function y(e){switch(e){case i.statusNames.approved:return"badge-success";case i.statusNames.rejected:return"badge-danger";case i.statusNames.cancelled:case"all":return"";default:return"badge-primary"}}function _(t){return e.find(U.leaveRequestStatuses,function(e){return e.name===t}).value}function q(t){var n=e.find(U.filteredUsers,function(e){return e.id===t});return n?n.display_name:null}function $(e){return e.current?"Current Period ("+e.title+")":e.title}function C(){return u.all().then(function(t){U.absencePeriods=e.sortBy(t,"start_date"),U.filters.leaveRequest.selectedPeriod=e.find(U.absencePeriods,function(e){return!!e.current})})}function A(){return c.all().then(c.loadCalculationUnits).then(function(e){U.absenceTypes=e})}function w(e){return(U.isAdmin?r.all(p()):r.leaveManagees(U.contactId,p())).then(function(t){return U.filteredUsers=U.isAdmin?t.list:t,e?R(e):n.all([R("table"),R("filter")])}).then(function(){U.filters.leaveRequest.leaveStatus!==H&&0===U.leaveRequests.table.list.length&&U.refresh(1,!0)})}function P(){return s.valuesOf("hrjc_department").then(function(e){U.departments=e})}function R(e){var t="filter"!==e,n="table"===e?e:"content",a="filter"===e?{size:0}:U.pagination,r="filter"===e?{return:["status_id"]}:{};return U.loading[n]=!0,l.all(T(t),a,"from_date DESC",r,!1).then(function(t){U.leaveRequests[e]=t}).catch(function(){U.leaveRequests[e].list=[]}).finally(function(){U.loading[n]=!1})}function D(){return s.valuesOf("hrjc_level_type").then(function(e){U.levelTypes=e})}function S(){return s.valuesOf("hrjc_location").then(function(e){U.locations=e})}function T(t){var n=U.filters.leaveRequest;return{contact_id:M(),managed_by:U.isAdmin&&"me"!==n.assignedTo.type?void 0:U.contactId,status_id:x(t),type_id:n.selectedAbsenceTypes?n.selectedAbsenceTypes.id:{IN:e.pluck(U.absenceTypes,"id")},from_date:{from:n.selectedPeriod.start_date},to_date:{to:n.selectedPeriod.end_date},unassigned:"unassigned"===n.assignedTo.type||void 0}}function I(){return s.valuesOf("hrjc_region").then(function(e){U.regions=e})}function O(){return s.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){U.leaveRequestStatuses=e.concat(U.leaveRequestStatuses)})}function L(e,t,n,a){d.openModal.apply(d,arguments)}function M(){return U.filteredUsers.length>0&&U.filters.leaveRequest.contact_id?U.filters.leaveRequest.contact_id:{IN:U.filteredUsers.map(function(e){return e.id})}}function k(e){var t=[_(i.statusNames.moreInformationRequired),_(i.statusNames.awaitingApproval)];return 0===e.length&&(e=e.concat(t)),e}function x(e){var t=U.filters.leaveRequest,n=[];if(e&&t.leaveStatus&&t.leaveStatus.value&&n.push(t.leaveStatus.value),t.pending_requests&&(n=k(n)),n.length)return{IN:n}}function E(e,t,n){e="number"==typeof e?e:1,t&&(U.filters.leaveRequest.leaveStatus=H),(e<=U.totalNoOfPages()||0===U.totalNoOfPages())&&(U.pagination.page=e,w(n))}function j(e){U.filters.leaveRequest.leaveStatus=e,U.refresh(1,!1,"table")}function B(e){U.filters.leaveRequest.assignedTo=e,U.refresh()}function N(){f.subscribe("LeaveRequest::updatedByManager",function(){U.refresh()}),f.subscribe("LeaveRequest::new",function(){U.refresh()}),f.subscribe("LeaveRequest::edit",function(){U.refresh()}),f.subscribe("LeaveRequest::delete",function(){U.refresh()}),f.subscribe("LeaveRequest::statusUpdate",function(){U.refresh()})}function F(){return Math.ceil(U.leaveRequests.table.total/U.pagination.size)}t.debug("Component: manage-leave-requests");var U=this,H={name:"all",label:"All"};U.absencePeriods=[],U.absenceTypes=[],U.filteredUsers=[],U.isFilterExpanded=!1,U.isAdmin=!1,U.leaveRequests={table:{list:[]},filter:{list:[]}},U.leaveRequestStatuses=[H],U.loading={content:!0,page:!0,table:!0},U.pagination={page:1,size:7},U.filtersByAssignee=[{type:"me",label:"Assigned To Me"},{type:"unassigned",label:"Unassigned"},{type:"all",label:"All"}],U.filters={contact:{department:null,level_type:null,location:null,region:null},leaveRequest:{leaveStatus:U.leaveRequestStatuses[0],pending_requests:!0,contact_id:null,selectedPeriod:null,selectedAbsenceTypes:null,assignedTo:U.filtersByAssignee[0]}},U.clearStaffSelection=m,U.countLeaveRequestByStatus=v,U.getAbsenceTypeByID=h,U.getArrayOfSize=g,U.getLeaveStatusByValue=b,U.getNavBadge=y,U.getUserNameByID=q,U.labelPeriod=$,U.openLeavePopup=L,U.refresh=E,U.refreshWithFilter=j,U.refreshWithFilterByAssignee=B,U.totalNoOfPages=F,function(){o(i.permissions.admin.administer).then(function(e){U.isAdmin=e,n.all([C(),A(),I(),P(),S(),D(),O()]).then(function(){U.loading.page=!1,w()}),N()})}()}t.component("manageLeaveRequests",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/manage-leave-requests.html"}],controllerAs:"vm",controller:n}),n.$inject=["$log","$q","$rootScope","Contact","checkPermissions","OptionGroup","shared-settings","AbsencePeriod","AbsenceType","LeaveRequest","LeavePopup","pubSub"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["leave-absences/shared/modules/controllers"],function(e){function t(e,t,n,a){function r(){return a.request.calculateBalanceChange(a.selectedAbsenceType.calculation_unit_name)}function o(){var e=a.request,t=!!e.from_date&&!!e.to_date,n=a.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function s(){return a.canCalculateChange()}function i(){return n.resolve()}t.debug("RequestModalDetailsLeaveController"),a.calculateBalanceChange=r,a.canCalculateChange=o,a.canSubmit=s,a.initChildController=i}e.controller("RequestModalDetailsLeaveController",t),t.$inject=["$controller","$log","$q","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o){function s(){return!(!o.canCalculateChange()||!o.request.sickness_reason)}function i(){return a.all([l(),d()])}function u(t){var n=o.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function c(t){return!!e.find(o.sicknessDocumentTypes,function(e){return e.value===t})}function l(){return r.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){o.sicknessDocumentTypes=e})}function d(){return r.valuesOf("hrleaveandabsences_sickness_reason").then(function(t){o.sicknessReasons=e.indexBy(t,"name")})}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:o}),o.canSubmit=s,o.initChildController=i,o.isChecked=u,o.isDocumentInRequest=c}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s){function i(){ -return s.balance.change.amount=+s.request.toil_to_accrue,n.resolve(s.balance.change)}function u(){return m().catch(function(e){return e.length&&(s.errors=e),n.reject(e)}).then(function(e){return o.calculateToilExpiryDate(s.request.type_id,e)}).then(function(e){return s.request.toil_expiry_date=e,s.uiOptions.expiryDate=new Date(e),e})}function c(){return!!s.request.toil_to_accrue}function l(){var e=s.uiOptions.multipleDays&&!!s.request.to_date,t=!s.uiOptions.multipleDays&&!!s.request.from_date,n=t||e,a=A.from_date!==s.request.from_date||A.to_date!==s.request.to_date;return s.canDisplayToilExpirationField&&n&&w.hasExpirationFromAdminSettings&&a}function d(){return!!(s.request.from_date&&s.request.to_date&&s.request.toil_duration&&s.request.toil_to_accrue)}function f(){s.request.toil_expiry_date=!1,s.uiOptions.expiryDate=null}function m(){var e=s.uiOptions.multipleDays,t=s.request;return p({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function p(e){if(e.hasErrors){var t="Please select "+e.label+" to find expiry date";return n.reject([t])}return e.value?n.resolve(e.value):n.reject([])}function v(){var e=s.isMode("create")&&w.hasExpirationFromAdminSettings,t=w.hasPreviousExpirationDate,n=s.isLeaveType("toil"),a=s.canManage;s.canDisplayToilExpirationField=n&&(a||e||t)}function h(){return w.hasPreviousExpirationDate=s.isMode("edit")&&!!s.request.toil_expiry_date,o.canExpire(s.request.type_id).then(function(e){w.hasExpirationFromAdminSettings=e})}function g(){return s.request.to_date_type=s.request.from_date_type="1",h().then(v).then(b).then(_)}function b(){s.canManage&&(s.uiOptions.expiryDate=s.convertDateFormatFromServer(s.request.toil_expiry_date))}function y(){s.isMode("view")||a.$watch(function(){return s.request.toil_to_accrue},function(e,t){+e!=+t&&s.performBalanceChangeCalculation()})}function _(){return r.valuesOf("hrleaveandabsences_toil_amounts").then(function(t){s.toilAmounts=e.indexBy(t,"value")})}function q(){A=angular.copy(s.request.attributes())}function $(){return l()?u().catch(n.resolve):n.resolve()}function C(){s.uiOptions.expiryDate&&(s.request.toil_expiry_date=s.convertDateToServerFormat(s.uiOptions.expiryDate))}t.debug("RequestModalDetailsToilController");var A,w={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};s.canDisplayToilExpirationField=!1,s.calculateBalanceChange=i,s.canCalculateChange=c,s.canSubmit=d,s.clearExpiryDate=f,s.initChildController=g,s.onDateChangeExtended=$,s.setDaysSelectionModeExtended=$,s.updateExpiryDate=C,function(){y(),q()}()}t.controller("RequestModalDetailsToilController",n),n.$inject=["$log","$q","$rootScope","api.optionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function f(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function m(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function v(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,m(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,m(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function h(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?v.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([h.call(this),f.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([h.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={toilDurationHours:"0",toilDurationMinutes:"0",request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},transformAttributes:function(e){var t=Number(e.toil_duration);return t&&(e.toilDurationHours=Math.floor(t/60).toString(),e.toilDurationMinutes=(t%60).toString()),e},updateDuration:function(){this.toil_duration=60*Number(this.toilDurationHours)+Number(this.toilDurationMinutes)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files","toilDurationHours","toilDurationMinutes"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,f,m,p,v,h,g,b,y,_,q,$,C){function A(e){"days"===ke.selectedAbsenceType.calculation_unit_name?delete ke.request[e+"_date_amount"]:delete ke.request[e+"_date_type"]}function w(){["from","to"].forEach(A)}function P(){var e=ke.requestStatuses[_.statusNames.awaitingApproval].value;Se.status_id===e&&e!==ke.request.status_id&&d.publish("ManagerBadge:: Update Count")}function R(){return Me.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function D(){return Me.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return!ke.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function T(){var e=R();return ke.isMode("edit")&&(e=e&&(V()||D())),ke.canManage&&ke.requestStatuses&&(e=e&&!!ke.getStatusFromValue(ke.newStatusOnSave)),(e=e&&!!ke.period.id)&&!ke.isMode("view")}function I(){ke.isSelfRecord?ke.request.status_id=ke.requestStatuses[_.statusNames.awaitingApproval].value:ke.canManage&&(ke.request.status_id=ke.newStatusOnSave||ke.request.status_id)}function O(){if(ke.isMode("edit")&&!ke.isRole("staff")&&"toil"!==F())return ke.request.calculateBalanceChange(ke.selectedAbsenceType.calculation_unit_name).then(function(e){if(+ke.balance.change.amount!=+e.amount)return C.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function L(){ke.errors=[]}function M(){return ke.request.create().then($e).then(function(){me("LeaveRequest::new")})}function k(){ee()&&!ke.isRole("staff")&&(ke.request.change_balance=!0)}function x(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return ke.request.delete().then(function(){ke.dismissModal(),d.publish("LeaveRequest::delete",ke.request)})}})}function E(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(ke.getStatusFromValue(ke.request.status_id).name)}function N(e){return n.map(Re[e],function(e){return ke.requestStatuses[e]})}function F(){return ke.request?ke.request.request_type:ke.leaveType||null}function U(){return!ke.request||e.equals({},ke.requestStatuses)?[]:ke.request.status_id?B():N("none")}function H(e){return n.find(ke.requestStatuses,function(t){return t.value===e})}function W(e){ke.errors=n.isArray(e)?e:[e],ke.loading.absenceTypes=!1,ke.submitting=!1}function V(){return!e.equals(Se,ke.request.attributes())||ke.canManage&&ke.newStatusOnSave}function G(){return ke.postContactSelection=!0,ke.staffMemberSelectionComplete=!1,ke.request.contact_id?r.resolve().then(ie).then(ue).then(ve).then(ge).then(Z).then(z).then(ke.isMode("edit")?be:n.noop).then(function(){ke.postContactSelection=!1,ke.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Oe)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];Re.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],Re.awaiting_approval=e,Re.more_information_required=e,Re.rejected=e,Re.approved=e,Re.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return ke.canManage?m.find(ke.request.contact_id).then(function(e){ke.contactName=e.display_name}):r.resolve()}function J(){Te.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(ve).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",ke.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){W(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){De++})),s.$on("$destroy",Ce),s.$on("LeaveRequestPopup::addTab",function(e,t){Me.push(t)})}function K(){var e,t;ke.request=ke.leaveRequest||null,e=F(),t=ke.initRequestAttributes(),"leave"===e?ke.request=y.init(t):"sickness"===e?ke.request=q.init(t):"toil"===e&&(ke.request=$.init(t))}function X(){var e={};return ke.request?e=ke.request.attributes():ke.canManage||(e={contact_id:Ie}),e}function Q(){if(Le="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(Le="admin")}).then(function(){return"staff"===Le&&u(_.permissions.ssp.manage).then(function(e){e&&(Le="manager")})}).finally(function(){ke.canManage=ke.isRole("manager")||ke.isRole("admin")})}function Z(){(ke.isRole("admin")||ke.isMode("create")&&ke.isRole("manager"))&&(ke.newStatusOnSave=ke.requestStatuses[_.statusNames.approved].value)}function ee(){return!ke.request.status_id||!n.includes(["cancelled","rejected"],H(ke.request.status_id).name)}function te(e){var t=ke.getStatusFromValue(ke.request.status_id);return!!t&&t.name===e}function ne(e){return ke.request&&ke.request.request_type===e}function ae(e){return ke.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date)&&r.isSameOrBefore(t.end_date)}function oe(e){return Le===e}function se(){return v.all().then(function(e){ke.absencePeriods=e})}function ie(){return h.all(j()).then(h.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return ke.loading.entitlements=!0,g.all({contact_id:ke.request.contact_id,period_id:ke.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){ke.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Ie=e.contactId})}function le(){return ke.selectedContactId?m.find(ke.selectedContactId).then(function(e){ke.managedContacts=[e]}):ke.isRole("admin")?m.all().then(function(e){ke.managedContacts=n.remove(e.list,function(e){return e.id!==Ie})}):m.find(Ie).then(function(e){return e.leaveManagees()}).then(function(e){ke.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){ke.requestStatuses=n.indexBy(e,"name")})}function fe(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function me(e){P(),d.publish(e,ke.request),ke.errors=[],ke.dismissModal()}function pe(){["from","to"].forEach(function(e){ke.request[e+"_date"]=Se[e+"_date"]})}function ve(e){if(ke.absenceTypes=fe(Pe.types,e),!ke.absenceTypes.length)return r.reject(Oe)}function he(){ke.period=n.find(ke.absencePeriods,function(e){return ke.isMode("create")?e.current:re(ke.request,e)})}function ge(){ke.isMode("create")?(ke.selectedAbsenceType=ke.absenceTypes[0],ke.request.type_id=ke.selectedAbsenceType.id):ke.selectedAbsenceType=n.find(ke.absenceTypes,function(e){return e.id===ke.request.type_id})}function be(){Se=e.copy(ke.request.attributes())}function ye(){var e;ke.request.id?(e=[ke.requestStatuses[_.statusNames.approved].value,ke.requestStatuses[_.statusNames.adminApproved].value,ke.requestStatuses[_.statusNames.rejected].value,ke.requestStatuses[_.statusNames.cancelled].value],ke.mode="edit",ke.isRole("staff")&&e.indexOf(ke.request.status_id)>-1&&(ke.mode="view")):ke.mode="create"}function _e(){var e=ke.request.status_id;if(!ke.isMode("view")&&!ke.submitting)return ke.submitting=!0,I(),w(),ke.request.isValid().then(ee()&&O).then(k).then(!ke.request.change_balance&&pe).then(qe).then(function(){return ke.isMode("edit")?we():M()}).catch(function(t){ke.request.status_id=e,t&&W(t)}).finally(function(){ke.submitting=!1})}function qe(){return r.all(Me.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===De&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return De>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function Ce(){Te.forEach(function(e){e()})}function Ae(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function we(){return ke.request.update().then($e).then(function(){ke.isRole("manager")?me("LeaveRequest::updatedByManager"):(ke.isRole("staff")||ke.isRole("admin"))&&me("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,Re={},De=0,Se={},Te=[],Ie="",Oe="No entitlement",Le="",Me=[],ke=n.assign(this,f);ke.absencePeriods=[],ke.absenceTypes=[],ke.canManage=!1,ke.contactName=null,ke.errors=[],ke.loading={absenceTypes:!0,entitlements:!0},ke.managedContacts=[],ke.mode="",ke.newStatusOnSave=null,ke.period={},ke.postContactSelection=!1,ke.requestStatuses={},ke.selectedAbsenceType={},ke.staffMemberSelectionComplete=!1,ke.submitting=!1,ke.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},ke.canChangeAbsenceType=S,ke.canSubmit=T,ke.closeAlert=L,ke.deleteLeaveRequest=x,ke.dismissModal=E,ke.getStatuses=U,ke.getStatusFromValue=H,ke.initAfterContactSelection=G,ke.initRequestAttributes=X,ke.isLeaveStatus=te,ke.isLeaveType=ne,ke.isMode=ae,ke.isRole=oe,ke.submit=_e,ke.updateAbsenceType=Ae,function(){ke.loading.absenceTypes=!0,Y(),J(),r.all([ce(),Q(),se(),de()]).then(K).then(ye).then(he).then(function(){return ke.canManage&&!ke.isMode("edit")&&le()}).then(function(){if(ke.selectedContactId&&(ke.request.contact_id=ke.selectedContactId),ke.request.contact_id)return ke.initAfterContactSelection()}).catch(W).finally(function(){ke.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/manager-leave/modules/components",["common/angular"],function(e){return e.module("manager-leave.components",[])}),define("leave-absences/manager-leave/components/manager-leave-container",["leave-absences/manager-leave/modules/components"],function(e){e.component("managerLeaveContainer",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/manager-leave-container.html"}],controller:["$log","$rootScope","$state",function(e,t,n){function a(){n.go(r.tabName)}e.debug("Component: manager-leave-container"),t.section="manager-leave";var r=this;r.tabName=n.current.name,r.changeTab=a}],controllerAs:"managerLeave"})}),function(e){define("leave-absences/manager-leave/modules/settings",["common/angular"],function(t){return t.module("manager-leave.settings",[]).constant("settings",{debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/manager-leave/"})})}(CRM),function(e){define("leave-absences/manager-leave/modules/config",["common/angular","leave-absences/manager-leave/modules/settings"],function(t){return t.module("manager-leave.config",["manager-leave.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(t,n,a,r,o,s){o.debugEnabled(s.debug),n.defaults.stripTrailingSlashes=!1,r.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",a.otherwise("/manager-leave/requests"),t.state("manager-leave",{abstract:!0,url:"/manager-leave",template:'',resolve:{contactId:function(){return e.vars.leaveAndAbsences.contactId},format:["DateFormat",function(e){return e.getDateFormat()}]}}).state("manager-leave.requests",{url:"/requests?leave-request-id",template:'',onEnter:["$stateParams","LeavePopup",function(e,t){e["leave-request-id"]&&t.openModalByID(e["leave-request-id"])}]}).state("manager-leave.calendar",{url:"/calendar",template:''}).state("manager-leave.leave-balances",{url:"/leave-balances",template:""})}])})}(CRM), -define("leave-absences/manager-leave/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/loading","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/services/angular-date/date-format","common/services/check-permissions","leave-absences/shared/ui-router","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/components/leave-balance-tab.component","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/manage-leave-requests.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/services/leave-popup.service","leave-absences/manager-leave/components/manager-leave-container","leave-absences/manager-leave/modules/config"],function(e){return e.module("manager-leave",["ngResource","ngAnimate","ui.bootstrap","ui.router","ui.select","textAngular","common.angularDate","common.dialog","common.filters","common.models","common.directives","common.mocks","leave-absences.models","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","manager-leave.config","manager-leave.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/manager-leave":n+"/manager-leave"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/manager-leave/app","leave-absences/shared/models/leave-request.model"],function(e){e.bootstrap(document.querySelector("[data-leave-absences-manager-leave]"),["manager-leave"])})})}(CRM,require),define("manager-leave",function(){}); +!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return W(new(W(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[f]),c[r[f]]=e[r[f]]);return W({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))v.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&m(u[e],e)}),v.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var h=s(u||{}),v=[],g=[],b={};return H(u,m),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),m.$$values=b,m.$$promises=m.$$promises||!0,delete m.$$inheritedValues,c.resolve(b))}function u(e){m.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),m=c.promise,g=m.$$promises={},b=W({},a),y=1+v.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),m;o.$$inheritedValues&&r(b,f(o.$$inheritedValues,h)),W(g,o.$$promises),o.$$values?(_=r(b,f(o.$$values,h)),m.$$inheritedValues=f(o.$$values,h),i()):(o.$$inheritedValues&&(m.$$inheritedValues=f(o.$$inheritedValues,h)),o.then(i,u));for(var q=0,$=v.length;q<$;q+=3)a.hasOwnProperty(v[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(m.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),f=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(f++,g[e].then(function(t){b[e]=t,--f||l()},c))}),f||l(),g[n]=d.promise}(v[q],v[q+1],v[q+2]);return m}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(v.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(h[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return h[t]=new Y.Param(t,n,a,r),h[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(f,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=W({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",f=0,m=this.segments=[],p=r?r.params:{},h=this.params=r?r.params.$$new():new Y.ParamSet,v=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),m.push(g.segment),f=c.lastIndex;y=e.substring(f);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,f+_),q.length>0)for(f=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),f=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",m.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=m[0],this.$$paramNames=v}function y(e){W(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:h,caseInsensitive:f}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){W(this,e||{})}Y=this;var d,f=!1,h=!0,v=!1,g={},q=!0,$=[],C={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(f=e),f},this.strictMode=function(e){return j(e)&&(h=e),h},this.defaultSquashPolicy=function(e){if(!j(e))return v;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return v=e,e},this.compile=function(e,t){return new b(e,W(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(W({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(C,function(e,t){g[t]=new y(W({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(C,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!h.type.is(e))throw new Error("Default value ("+e+") for parameter '"+h.id+"' is not an instance of Type ("+h.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(m(h.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?h.type.$normalize(e):c()}function f(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var h=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return W(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return v;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),m(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);W(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:f})},l.prototype={$$new:function(){return a(this,W(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return m(r,t.self);for(var o in T)B(T[o])&&(t[o]=T[o](t,T.$delegates[o]));return P[n]=t,!t[S]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){w.$current.navigable==t&&c(e,n)||w.transitionTo(t,e,{inherit:!0,location:!1})}]),v(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=w.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=E[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),T):(w.$current=t,w.current=t.self,w.params=n,V(w.params,m),w.transition=null,o.location&&t.navigable&&v.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),v.update(!0),w.current)}).then(null,function(a){return a===D?T:w.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),T):(w.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||v.update(),r.reject(a))});return B},w.is=function(e,t,a){a=W({relative:w.$current},a||{});var r=f(e,a.relative);return j(r)?w.$current===r&&(!t||c(r.params.$$values(t),m)):n},w.includes=function(e,t,a){if(a=W({relative:w.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=w.$current.name}var r=f(e,a.relative);if(!j(r))return n;if(!j(w.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(f&&(f.remove(),f=null),p&&(p.$destroy(),p=null),m){var e=m.data("$uiViewAnim");b.leave(m,function(){e.$$animLeave.resolve(),f=null}),f=m,m=null}}function d(s){var d,f=D(n,c,i,r),y=f&&e.$current&&e.$current.locals[f];if(s||y!==h){d=n.$new(),h=e.$current.locals[f],d.$emit("$viewContentLoading",f);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});m=_,p=d,p.$emit("$viewContentLoaded",f),p.$eval(v)}}var f,m,p,h,v=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=D(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var f=t.extend({},d);o[d.$$resolveAs]=f;var m=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=f),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}m(o)}}}}}function D(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function S(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function T(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function R(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function O(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function I(e,t){return{relative:T(e)||t.$current,inherit:!0}}function x(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=S(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=R(r),d=s[1]||s[0],f=null;c.options=W(I(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var m=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),f&&f(),d&&(f=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&m(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),m(),l.clickable&&(i=O(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function E(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){f.state=t[0],f.params=t[1],f.options=t[2],f.href=e.href(f.state,f.params,f.options),m&&m(),c&&(m=c.$$addStateInfo(f.state,f.params)),f.href&&r.$set(u.attr,f.href)}var i,u=R(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",f={state:null,params:null,options:null,href:null},m=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=O(a,e,t,u,function(){return f}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function L(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,T(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return h.push(u),v[s]=r,function(){var e=h.indexOf(u);-1!==e&&h.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function M(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function k(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,W=t.extend,V=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),v.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",v),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,W(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;a=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/components/leave-balance-tab-filters.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n){function a(e){e.absencePeriods&&c.absencePeriods.length&&(c.filters.period_id=o().id),e.absenceTypes&&c.absenceTypes.length&&(c.filters.type_id=s().id),(e.loggedInContactId||e.userRole)&&(c.filters.managed_by="manager"===c.userRole?c.loggedInContactId:void 0),r()&&c.submitFilters()}function r(){return e.every(c.filters,function(e){return null!==e})}function o(){return e.find(c.absencePeriods,function(e){return e.current})||c.absencePeriods.reduce(function(e,n){return t(e.end_date).isAfter(n.end_date)?e:n})}function s(){return c.absenceTypes.reduce(function(e,t){return e.title.localeCompare(t.title)?e:t})}function i(e){return e.current?"Current Period ("+e.title+")":e.title}function u(){n.$emit("LeaveBalanceFilters::update",c.filters)}var c=this;c.filters={period_id:null,type_id:null,managed_by:null},c.$onChanges=a,c.labelPeriod=i,c.submitFilters=u}n.component("leaveBalanceTabFilters",{controller:a,controllerAs:"balanceFilters",bindings:{absencePeriods:"<",absenceTypes:"<",loggedInContactId:"<",lookupContacts:"<",userRole:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-balance-tab-filters.html"}]}),a.$inject=["$scope"]}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,n){function a(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(n.remainder=a[0].remainder),delete n["api.LeavePeriodEntitlement.getremainder"],n}function r(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return n.value=a,delete n["api.LeavePeriodEntitlement.getentitlement"],n}return e.debug("EntitlementAPI"),n.extend({all:function(t,n){return e.debug("EntitlementAPI.all"),t["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},n&&(t["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",t,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r),n&&(e=e.map(a)),e})},breakdown:function(t){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",t).then(function(e){return e.values})},getLeaveBalances:function(t,n,a,r,o){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",t,n,a,r,"getLeaveBalances",o)}})}])}),define("leave-absences/shared/models/leave-balance-report.model",["leave-absences/shared/modules/models","leave-absences/shared/apis/entitlement.api","common/models/model"],function(e){"use strict";e.factory("LeaveBalanceReport",["Model","EntitlementAPI",function(e,t){return e.extend({all:function(e,n,a,r,o){return t.getLeaveBalances(this.processFilters(e),n,a,r,o)}})}])}),define("leave-absences/shared/components/leave-balance-tab.component",["common/angular","common/lodash","leave-absences/shared/modules/components","leave-absences/shared/components/leave-balance-tab-filters.component","leave-absences/shared/models/leave-balance-report.model","common/services/notification.service","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f){function m(){return r.all({options:{sort:"title ASC"}}).then(function(e){P.absencePeriods=e})}function p(){return o.all().then(o.loadCalculationUnits).then(function(e){P.absenceTypes=e})}function h(){return s.all(null,null,"sort_name ASC").then(function(e){P.lookupContacts=e.list})}function v(){return n.all([m(),p(),h(),g(),q()]).catch(function(e){u.error("Error",e)})}function g(){return l.get().then(function(e){P.loggedInContactId=e.contactId})}function b(){return P.loading.report=!0,i.all(w,P.pagination,void 0,void 0,!1).then(function(e){P.report=y(e.list),P.reportCount=e.total}).catch(function(e){u.error("Error",e.error_message)}).finally(function(){P.loading.report=!1})}function y(n){return n.map(function(n){return n=e.copy(n),n.absence_types=t.indexBy(n.absence_types,function(e){return e.id}),n})}function _(){a.$on("LeaveBalanceFilters::update",C),c.subscribe("LeaveRequest::new",$)}function q(){return f(d.permissions.admin.administer).then(function(e){P.userRole=e?"admin":"manager"})}function $(e){C(e,w)}function C(e,t){w=t,P.pagination.page=1,A(),P.loadReportCurrentPage()}function A(){P.selectedAbsenceTypes=P.absenceTypes.filter(function(e){return+e.id==+w.type_id})}var w={},P=this;P.absencePeriods=[],P.absenceTypes=[],P.loading={component:!0,report:!0},P.loggedInContactId=null,P.lookupContacts=[],P.pagination={page:1,size:50},P.report=[],P.reportCount=0,P.userRole=null,P.loadReportCurrentPage=b,function(){_(),v().then(function(){P.loading.component=!1})}()}n.component("leaveBalanceTab",{controller:a,controllerAs:"leaveBalanceTab",templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-balance-tab.html"}]}),a.$inject=["$q","$rootScope","AbsencePeriod","AbsenceType","Contact","LeaveBalanceReport","notificationService","pubSub","Session","shared-settings","checkPermissions"]}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,t,n){function a(n,a,r,o,s,i){function u(){return d().then(function(n){var a=n.filter(function(e){var n=e.info.details;return t(n.period_start_date).isSameOrBefore(v.selectedPeriod.end_date)&&(t(n.period_end_date).isSameOrAfter(v.selectedPeriod.start_date)||!n.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function c(){return{loadContacts:function(){var e=v.filters.userSettings.assignedTo.type;return f(e).then(function(e){v.lookupContacts=e}).then(function(){return"me"!==e?u():a.resolve(null)}).then(function(e){return v.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return r.all(m(),null,"display_name").then(function(e){return e.list})}function d(){return h?a.resolve(h):s.all()}function f(e){return"me"===e?r.leaveManagees(v.contactId):"unassigned"===e?r.leaveManagees(void 0,{unassigned:!0}):r.all().then(function(e){return e.list})}function m(){return{department:v.filters.userSettings.department?v.filters.userSettings.department.value:null,level_type:v.filters.userSettings.level_type?v.filters.userSettings.level_type.value:null,location:v.filters.userSettings.location?v.filters.userSettings.location.value:null,region:v.filters.userSettings.region?v.filters.userSettings.region.value:null,id:{IN:v.filters.userSettings.contact?[v.filters.userSettings.contact.id]:v.lookupContacts.map(function(e){return e.id})}}}function p(e){i.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,f){function m(){for(var e=[],t=n(E.selectedPeriod.start_date).clone().startOf("month"),a=n(E.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");E.months=e}function p(){s.$new().$watch(function(){return E.selectedMonths},function(t,n){null===n||e.equals(t,n)||S()})}function h(e){E.injectMonths=!0,O("injected").then(function(){S(e)}).then(function(){E.loading.calendar=!1})}function v(){I=a("LeaveCalendar"+t.capitalize(x)+"Controller").init(E)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){E.absencePeriods=t.sortBy(e,"start_date"),E.selectedPeriod=t.find(E.absencePeriods,function(e){return!!e.current})}).then(m).then(T)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return I.loadContacts().then(function(e){E.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){E.filters.optionValues.regions=e.hrjc_region,E.filters.optionValues.locations=e.hrjc_location,E.filters.optionValues.levelTypes=e.hrjc_level_type,E.filters.optionValues.departments=e.hrjc_department})}function C(){return l.all()}function A(){return r.all([y(),C(),_()]).then(function(e){E.supportData.absenceTypes=e[0],E.supportData.publicHolidays=e[1],E.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,E.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,E.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,E.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function w(){var e=r.resolve();return E.injectMonths&&(e=O("destroyed"),E.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function D(e){e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){E.loading.calendar=!0}).then(w).then("period"===e?m:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function S(e){var n=E.selectedMonths.length?E.months.filter(function(e){return t.includes(E.selectedMonths,e.index)}):E.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function T(){E.selectedMonths=[n().month()]}function R(){return E.roleOverride?r.resolve().then(function(){x=E.roleOverride}):r.all([f(i.permissions.admin.administer),f(i.permissions.ssp.manage)]).then(function(e){x=e[0]?"admin":e[1]?"manager":"staff"})}function O(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===E.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var I,x,E=this;E.absencePeriods=[],E.contacts=[],E.contactIdsToReduceTo=null,E.injectMonths=!1,E.months=[],E.selectedMonths=null,E.selectedPeriod=null,E.showContactName=!1,E.showFilters=!1,E.supportData={},E.loading={calendar:!0,page:!0},E.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},E.labelPeriod=g,E.refresh=D,function(){R().then(p).then(v).then(w).then(b).then(function(){return r.all([q(),A()])}).then(function(){return E.showFilters?$():t.noop}).then(function(){h()}).then(function(){E.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r,o){"use strict";function s(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function i(e){return e.isAM?"AM":e.isPM?"PM":""}function u(e){var n=t(e.from_date).isSame(g.date,"day"),a=t(e.to_date).isSame(g.date,"day");return n?t(e.from_date).format("HH:mm"):a?t(e.to_date).format("HH:mm"):""}function c(t,n){g.contactData.leaveRequestsAttributes[t.id].absenceTypeTitle=e.find(g.supportData.absenceTypes,{id:t.type_id}).title}function l(t,n){var a=e.find(g.supportData.absenceTypes,{id:t.type_id}),r=e.find(g.supportData.calculationUnits,{value:a.calculation_unit});n.unit=r.name}function d(e,t){t.from_date=new Date(e.from_date),t.to_date=new Date(e.to_date)}function f(t,n){"days"===n.unit&&(n.from_date_type=e.find(g.supportData.dayTypes,{value:t.from_date_type}).label,n.to_date_type=e.find(g.supportData.dayTypes,{value:t.to_date_type}).label)}function m(e,t){var n="";n=t.isAccruedTOIL?"AT":"days"===t.unit?i(t):u(e),t.label=n}function p(e){var t=g.contactData.leaveRequestsAttributes[e.id];[l,f,m,d,c].forEach(function(n){n.call(this,e,t)})}function h(e,t){r(function(){g.tooltip[e+"_hovered"]=t,g.tooltip.show=g.tooltip.day_cell_hovered||g.tooltip.tooltip_hovered},t?0:100)}function v(){a.$watch("day.contactData.leaveRequests",function(){g.contactData&&g.contactData.leaveRequests&&g.contactData.leaveRequests.forEach(p)},!0)}n.debug("Component: leave-calendar-day");var g=this;g.tooltip={show:!1,day_cell_hovered:!1,tooltip_hovered:!1},g.openLeavePopup=s,g.toggleTooltip=h,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","$timeout","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){q([e]),U(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(Y.period.start_date)&&r.isSameOrBefore(Y.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function f(e){return V[e]}function m(){return Y.showOnlyWithLeaveRequests?Y.contacts.filter(function(e){return Object.keys(G[e.id]||{}).length}):Y.contacts}function p(e){return t(e,u.serverDateFormat)}function h(e){var t=g(e);t&&(E(t),U(t))}function v(t){var n={request_type:"toil"};return e.some(t,n)&&!e.every(t,n)?e.filter(t,n):t}function g(t){var n;return e.find(G[t.contact_id],function(a){return n=e.find(a,function(e){return+e.id==+t.id})}),n}function b(e){return CRM.url("civicrm/contact/view",{cid:e})}function y(e,n){var a={};return n.forEach(function(n){a[n.id]={styles:N(n),isAccruedTOIL:A(n,"toil"),isRequested:P(n),isAM:C("half_day_am",n,e.date),isPM:C("half_day_pm",n,e.date),isSingleDay:t(n.from_date).isSame(n.to_date,"day")}}),a}function _(){Y.supportData.dayTypes=e.indexBy(Y.supportData.dayTypes,"name"),Y.supportData.leaveRequestStatuses=e.indexBy(Y.supportData.leaveRequestStatuses,"value"),Y.supportData.publicHolidays=e.transform(Y.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function q(e){return e.forEach(function(e){var t=D(e);G[e.contact_id]=G[e.contact_id]||{},t.forEach(function(t){G[e.contact_id][t.date]||(G[e.contact_id][t.date]=[]),G[e.contact_id][t.date].push(e)})}),a.resolve()}function $(){W.push(r.$on("LeaveCalendar::showMonths",j)),W.push(i.subscribe("LeaveRequest::new",c)),W.push(i.subscribe("LeaveRequest::edit",F)),W.push(i.subscribe("LeaveRequest::updatedByManager",F)),W.push(i.subscribe("LeaveRequest::delete",h)),W.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):F(e.leaveRequest)}))}function C(e,n,a){var r=Y.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function A(e,t){return e.request_type===t}function w(e){return!!Y.supportData.publicHolidays[p(e).valueOf()]}function P(t){var n=Y.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function D(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===Y.month.index&&r.year()===Y.month.year&&a.push(e.find(Y.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function S(t){var n=e.find(Y.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function T(){return[S(u.statusNames.approved),S(u.statusNames.adminApproved),S(u.statusNames.awaitingApproval),S(u.statusNames.moreInformationRequired)]}function R(){return Y.month.loading=!0,a.all([I(),O()]).then(x).then(k).then(function(){H=!0,Y.month.loading=!1})}function O(){return s.all({from_date:{to:Y.month.days[Y.month.days.length-1].date},to_date:{from:Y.month.days[0].date},status_id:{IN:T()},contact_id:{IN:Y.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(Y.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return q(e.list)})}function I(){var t=Y.month.days[0].date,n=Y.month.days[Y.month.days.length-1].date;return o.get(Y.contacts.map(function(e){return e.id}),t,n).then(function(t){V=e.indexBy(t,"contact_id")})}function x(){return Y.contactIdsToReduceTo&&(Y.contacts=Y.contacts.filter(function(t){return e.includes(Y.contactIdsToReduceTo,t.contact_id)||e.find(G,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function E(t){var n=D(t);G[t.contact_id]=G[t.contact_id]||{},n.forEach(function(n){e.remove(G[t.contact_id][n.date],function(e){return e.id===t.id})})}function L(){r.$emit("LeaveCalendar::monthDestroyed"),W.map(function(e){e.remove?e.remove():e()})}function M(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=f(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:w(t.date)})}),o.then(function(){return G[n]&&G[n][t.date]?G[n][t.date]:[]}).then(function(a){a=B(a),e.assign(t.contactsData[n],{leaveRequests:a,leaveRequestsToShowInCell:v(a),leaveRequestsAttributes:y(t,a)})})}function k(){return a.all(Y.month.days.map(function(e){return a.all(Y.contacts.map(function(t){return M(e,t.id)}))}))}function j(t,n,a){!e.find(n,function(e){return e.index===Y.month.index})?Y.visible=!1:(Y.currentPage=0,Y.visible=!0,(a||!H)&&R())}function B(n){return e.sortBy(n,function(e){return+t(e.from_date).format("X")+(C("half_day_pm",e,e.from_date)?1:0)})}function N(t){var n=e.find(Y.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function F(e){h(e),-1!==T().indexOf(e.status_id)&&c(e)}function U(e){return a.all(D(e).map(function(t){return M(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var H=!1,W=[],V={},G={},Y=this;Y.currentPage=0,Y.pageSize=20,Y.visible=!1,Y.showContactName=!!Y.showContactName,Y.showOnlyWithLeaveRequests=!!Y.showOnlyWithLeaveRequests,Y.$onDestroy=L,Y.contactsList=m,Y.getContactUrl=b,function(){var e=t().month(Y.month.index).year(Y.month.year);_(),$(),Y.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o, +promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(h(t)):m(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function f(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||("manager"===q.role?e.includes([$.awaitingApproval,$.moreInformationRequired],n):"3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a)}function m(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=C[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function v(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(C,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!f(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:C[e].label,isDirectAction:C[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,C={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function f(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function m(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=f,q.getActiveComments=m,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f){function m(){te.balance.closing=te.balance.opening+te.balance.change.amount}function p(e){return t(e,u.serverDateFormat).toDate()}function h(e){return t(e).format(u.serverDateFormat)}function v(e){var t;return s.resolve().then(function(){F(e),"from"===e&&N(),O("hours")&&(y(e),"from"!==e||te.uiOptions.multipleDays||y("to")),te.loading[e+"DayTypes"]=!0}).then(function(){return q(e)}).then(function(e){if(t=e.id!==te.period.id,t&&(te.period=e),!te.period.id)return s.reject("Please change date as it is not in any absence period")}).then(H).then(function(){if(t)return L()}).then(function(){return te.onDateChangeExtended&&te.onDateChangeExtended(e)}).then(function(){if(Y(),!t)return k();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(w).finally(_)}function g(){return Y(),k()}function b(){return te.uiOptions.toDate=null,F("to"),s.resolve().then(Y).then(te.setDaysSelectionModeExtended).then(_).then(!te.uiOptions.multipleDays&&k)}function y(e){te.uiOptions.times[e].loading=!0}function _(){["from","to"].forEach(function(e){te.loading[e+"DayTypes"]=!1,O("hours")&&(te.uiOptions.times[e].loading=!1)})}function q(n){var a=t(te.uiOptions[n+"Date"]).format(te.uiOptions.userDateFormat.toUpperCase());return e.find(te.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function $(){return te.request?te.request.request_type:te.leaveType||null}function C(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function A(){return z(),te.loading.balanceChange=!0,te.request.getBalanceChangeBreakdown().then(U).catch(w)}function w(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),te.loading.fromDayTypes=!1,te.loading.balanceChange=!1,te.loading.tab=!1,te.loading.toDayTypes=!1}function P(){return te.isMode("create")||te.forceRecalculateBalanceChange?k():A()}function D(){var e=te.request.attributes();return te.uiOptions.fromDate=p(te.request.from_date),te.request.to_date=e.to_date,te.request.to_date_type=e.to_date_type,te.uiOptions.toDate=p(te.request.to_date),te.initDayTypesExtended?te.initDayTypesExtended():s.resolve()}function S(){ee.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){J()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){K(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",k))}function T(){te.isMode("edit")&&(te.isLeaveStatus(u.statusNames.approved)||te.isLeaveStatus(u.statusNames.adminApproved))&&(Z={absenceTypeId:te.request.type_id,value:te.selectedAbsenceType.remainder-te.request.balance_change})}function R(){r.$watch(function(){return te.uiOptions.times.from.time},function(e,t){e!==t&&(te.uiOptions.multipleDays||(Q(e),Y()))})}function O(e){return te.selectedAbsenceType.calculation_unit_name===e}function I(e){return te.request.request_type===e}function x(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function E(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){te.requestDayTypes=e})}function L(){return c.get(te.request.contact_id,te.period.start_date,te.period.end_date).then(function(e){te.calendar=e})}function M(){var e=(te.pagination.currentPage-1)*te.pagination.numPerPage,t=e+te.pagination.numPerPage;te.pagination.filteredbreakdown=te.balance.change.breakdown.slice(e,t)}function k(){return z(),te.canCalculateChange()?(te.loading.balanceChange=!0,te.request.change_balance=!0,te.calculateBalanceChange().then(U).catch(w).finally(function(){te.loading.balanceChange=!1})):s.resolve()}function j(){te.pagination.totalItems=te.balance.change.breakdown.length,te.pagination.filteredbreakdown=te.balance.change.breakdown,te.pagination.pageChanged()}function B(){return h(te.request.from_date)===h(te.request.to_date)}function N(){te.uiOptions.toDate&&te.uiOptions.fromDate&&te.uiOptions.multipleDays&&t(te.uiOptions.toDate).isSameOrBefore(te.uiOptions.fromDate)&&(te.uiOptions.toDate=null,F("to"))}function F(e){te.resetUIInputsExtended&&te.resetUIInputsExtended(e),Y(),z()}function U(e){te.balance.change=e,te.request.balance_change=e.amount,m(),j(),te.loading.balanceChange=!1}function H(){var e,n,a;te.uiOptions.fromDate?(e=t(te.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=p(te.period.start_date),n=te.uiOptions.date.to.options.minDate),te.uiOptions.date.to.options.initDate=n,te.uiOptions.date.to.options.minDate=a,te.uiOptions.date.to.options.maxDate=p(te.period.end_date)}function W(){return!te.isMode("create")&&B()||te.isMode("create")&&(I("sickness")||O("hours"))?te.uiOptions.multipleDays=!1:te.uiOptions.multipleDays=!0,s.resolve().then(te.setDaysSelectionModeExtended)}function V(){Z&&Z.absenceTypeId===te.selectedAbsenceType.id?te.balance.opening=Z.value||0:te.balance.opening=te.selectedAbsenceType.remainder}function G(){te.selectedAbsenceType=e.find(te.absenceTypes,function(e){return e.id===te.request.type_id})}function Y(){var e=te.uiOptions,t=e.times;te.request.from_date=e.fromDate?h(e.fromDate):null,te.request.to_date=e.toDate?h(e.toDate):null,!e.multipleDays&&e.fromDate&&(te.request.to_date=te.request.from_date,te.request.to_date_type=te.request.from_date_type),(O("hours")||I("toil"))&&(te.request.from_date=te.request.from_date&&t.from.time?te.request.from_date+" "+t.from.time:null,te.request.to_date=te.request.to_date&&t.to.time?te.request.to_date+" "+t.to.time:null)}function z(){te.uiOptions.showBalance=te.canCalculateChange()}function X(){e.forEach(ee,function(e){e()})}function J(){var e,t=te.selectedAbsenceType.calculation_unit_name;return G(),e=t!==te.selectedAbsenceType.calculation_unit_name,V(),s.resolve().then(e&&W).then(e&&te.onAbsenceTypeUpdateExtended).then(e&&Y).then(_).then(k)}function K(e){return te.absenceTypes=e,G(),t(te.uiOptions.toDate).isAfter(te.period.end_date)&&(te.uiOptions.toDate=void 0,F("to")),V(),k()}function Q(e){var t=C(e).add(te.uiOptions.time_interval,"minutes");t.isAfter(C(te.uiOptions.times.to.max))||(te.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(C(te.uiOptions.times.to.time))&&(te.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var Z=null,ee=[],te=this;te.canManage=!1,te.calendar={},te.errors=[],te.isRequired=!0,te.requestDayTypes=[],te.statusNames=u.statusNames,te.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},te.pagination={currentPage:1,filteredbreakdown:te.balance.change.breakdown,numPerPage:7,totalItems:te.balance.change.breakdown.length,pageChanged:M},te.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},te.convertDateFormatFromServer=p,te.convertDateToServerFormat=h,te.dateChangeHandler=v,te.dateTypeChangeHandler=g,te.daysSelectionModeChangeHandler=b,te.disableAndShowLoadingTimeInput=y,te.getMomentDateWithGivenTime=C,te.handleError=w,te.isCalculationUnit=O,te.isLeaveType=I,te.isNotWorkingDay=x,te.performBalanceChangeCalculation=k,te.setRequestDateTimesAndDateTypes=Y,te.updateEndTimeInputMinTime=Q,te.$onDestroy=X,function(){n("RequestModalDetails"+e.capitalize($(te.leaveType,te.request))+"Controller",{detailsController:te}),te.canManage=te.isRole("manager")||te.isRole("admin"),te.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",te),S(),te.initChildController().then(function(){return s.all([L(),E()])}).then(!te.isMode("create")&&D).then(W).then(function(){if(!te.isMode("create"))return s.resolve().then(te.initTimesExtended).then(Y)}).then(!te.isMode("create")&&H).then(T).then(V).then(P).then(R).then(!te.isMode("view")&&te.initWatchersExtended).catch(w).finally(function(){te.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return R.fileUploader&&R.fileUploader.queue.length>0}function f(){return R.getFilesAmount()0?D.map(function(e){return e.label}).join(", "):""}function q(){return R.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(D.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){T[e.label]=t})})).catch(function(){T=null})}function C(){return u.valuesOf("safe_file_extension").then(function(e){D=e})}function A(e){return!e.attachment_id||R.canManage}function w(){e.forEach(S,function(e){e()})}function P(e,t){R.fileUploader.queue&&R.fileUploader.queue.length>0?R.fileUploader.uploadAll({entityID:R.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var D=[],S=[],T={},R=Object.create(this);return R.filesLoaded=!1,R.fileUploader=null,R.today=Date.now(),R.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",R.userDateFormat=s.DATE_FORMAT,R.$onDestroy=w,R.canRemoveAttachment=A,R.canSubmit=d,R.canUploadMore=f,R.formatDateTime=m,R.getAuthorName=p,R.getFilesAmount=h,R.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",R),b(),a.all([C(),q()]).then(y).finally(function(){R.filesLoaded=!0})}(),R}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{contactId:"<",isSelfRecord:"<",selectedContactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/manage-leave-requests.component",["common/lodash","leave-absences/shared/modules/components","common/models/contact","common/services/pub-sub"],function(e,t){function n(t,n,a,r,o,s,i,u,c,l,d,f){"use strict";function m(){U.filters.leaveRequest.contact_id=null,U.refresh()}function p(){var e=U.filters.contact;return{department:e.department,level_type:e.level_type,location:e.location,region:e.region}}function h(e){return"all"===e.name||""===e?U.leaveRequests.filter.list.length:U.leaveRequests.filter.list.filter(function(t){return t.status_id===e.value}).length}function v(t){return e.find(U.absenceTypes,{id:t})}function g(e){return new Array(e||0)}function b(t){var n=e.find(U.leaveRequestStatuses,function(e){return e.value===t});return n?n.label:null}function y(e){switch(e){case i.statusNames.approved:return"badge-success";case i.statusNames.rejected:return"badge-danger";case i.statusNames.cancelled:case"all":return"";default:return"badge-primary"}}function _(t){return e.find(U.leaveRequestStatuses,function(e){return e.name===t}).value}function q(t){var n=e.find(U.filteredUsers,function(e){return e.id===t});return n?n.display_name:null}function $(e){return e.current?"Current Period ("+e.title+")":e.title}function C(){return u.all().then(function(t){U.absencePeriods=e.sortBy(t,"start_date"),U.filters.leaveRequest.selectedPeriod=e.find(U.absencePeriods,function(e){return!!e.current})})}function A(){return c.all().then(c.loadCalculationUnits).then(function(e){U.absenceTypes=e})}function w(e){return(U.isAdmin?r.all(p()):r.leaveManagees(U.contactId,p())).then(function(t){return U.filteredUsers=U.isAdmin?t.list:t,e?D(e):n.all([D("table"),D("filter")])}).then(function(){U.filters.leaveRequest.leaveStatus!==H&&0===U.leaveRequests.table.list.length&&U.refresh(1,!0)})}function P(){return s.valuesOf("hrjc_department").then(function(e){U.departments=e})}function D(e){var t="filter"!==e,n="table"===e?e:"content",a="filter"===e?{size:0}:U.pagination,r="filter"===e?{return:["status_id"]}:{};return U.loading[n]=!0,l.all(R(t),a,"from_date DESC",r,!1).then(function(t){U.leaveRequests[e]=t}).catch(function(){U.leaveRequests[e].list=[]}).finally(function(){U.loading[n]=!1})}function S(){return s.valuesOf("hrjc_level_type").then(function(e){U.levelTypes=e})}function T(){return s.valuesOf("hrjc_location").then(function(e){U.locations=e})}function R(t){var n=U.filters.leaveRequest;return{contact_id:E(),managed_by:U.isAdmin&&"me"!==n.assignedTo.type?void 0:U.contactId,status_id:M(t),type_id:n.selectedAbsenceTypes?n.selectedAbsenceTypes.id:{IN:e.pluck(U.absenceTypes,"id")},from_date:{from:n.selectedPeriod.start_date},to_date:{to:n.selectedPeriod.end_date},unassigned:"unassigned"===n.assignedTo.type||void 0}}function O(){return s.valuesOf("hrjc_region").then(function(e){U.regions=e})}function I(){return s.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){U.leaveRequestStatuses=e.concat(U.leaveRequestStatuses)})}function x(e,t,n,a){d.openModal.apply(d,arguments)}function E(){return U.filteredUsers.length>0&&U.filters.leaveRequest.contact_id?U.filters.leaveRequest.contact_id:{IN:U.filteredUsers.map(function(e){return e.id})}}function L(e){var t=[_(i.statusNames.moreInformationRequired),_(i.statusNames.awaitingApproval)];return 0===e.length&&(e=e.concat(t)),e}function M(e){var t=U.filters.leaveRequest,n=[];if(e&&t.leaveStatus&&t.leaveStatus.value&&n.push(t.leaveStatus.value),t.pending_requests&&(n=L(n)),n.length)return{IN:n}}function k(e,t,n){e="number"==typeof e?e:1,t&&(U.filters.leaveRequest.leaveStatus=H),(e<=U.totalNoOfPages()||0===U.totalNoOfPages())&&(U.pagination.page=e,w(n))}function j(e){U.filters.leaveRequest.leaveStatus=e,U.refresh(1,!1,"table")}function B(e){U.filters.leaveRequest.assignedTo=e,U.refresh()}function N(){f.subscribe("LeaveRequest::updatedByManager",function(){U.refresh()}),f.subscribe("LeaveRequest::new",function(){U.refresh()}),f.subscribe("LeaveRequest::edit",function(){U.refresh()}),f.subscribe("LeaveRequest::delete",function(){U.refresh()}),f.subscribe("LeaveRequest::statusUpdate",function(){U.refresh()})}function F(){return Math.ceil(U.leaveRequests.table.total/U.pagination.size)}t.debug("Component: manage-leave-requests");var U=this,H={name:"all",label:"All"};U.absencePeriods=[],U.absenceTypes=[],U.filteredUsers=[],U.isFilterExpanded=!1,U.isAdmin=!1,U.leaveRequests={table:{list:[]},filter:{list:[]}},U.leaveRequestStatuses=[H],U.loading={content:!0,page:!0,table:!0},U.pagination={page:1,size:7},U.filtersByAssignee=[{type:"me",label:"Assigned To Me"},{type:"unassigned",label:"Unassigned"},{type:"all",label:"All"}],U.filters={contact:{department:null,level_type:null,location:null,region:null},leaveRequest:{leaveStatus:U.leaveRequestStatuses[0],pending_requests:!0,contact_id:null,selectedPeriod:null,selectedAbsenceTypes:null,assignedTo:U.filtersByAssignee[0]}},U.clearStaffSelection=m,U.countLeaveRequestByStatus=h,U.getAbsenceTypeByID=v,U.getArrayOfSize=g,U.getLeaveStatusByValue=b,U.getNavBadge=y,U.getUserNameByID=q,U.labelPeriod=$,U.openLeavePopup=x,U.refresh=k,U.refreshWithFilter=j,U.refreshWithFilterByAssignee=B,U.totalNoOfPages=F,function(){o(i.permissions.admin.administer).then(function(e){U.isAdmin=e,n.all([C(),A(),O(),P(),T(),S(),I()]).then(function(){U.loading.page=!1,w()}),N()})}()}t.component("manageLeaveRequests",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/manage-leave-requests.html"}],controllerAs:"vm",controller:n}),n.$inject=["$log","$q","$rootScope","Contact","checkPermissions","OptionGroup","shared-settings","AbsencePeriod","AbsenceType","LeaveRequest","LeavePopup","pubSub"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return s.request.calculateBalanceChange(s.selectedAbsenceType.calculation_unit_name)}function l(){var e=s.request,t=!!e.from_date&&!!e.to_date,n=s.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function d(){return s.canCalculateChange()}function f(t,n){var a=s.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);s.uiOptions.multipleDays||("from"===t&&o&&r&&(o=s.getMomentDateWithGivenTime(o).subtract(s.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=s.getMomentDateWithGivenTime(r).add(s.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min}function m(t,n){return t?(t=s.convertDateToServerFormat(t),v(t).then(function(n){return n?s.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):p(t,s.requestDayTypes).then(function(t){return t.length?t:s.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return S(n,e),e})):r.reject([])}function p(e,n){return e=t(e),r.all([s.calendar.isNonWorkingDay(e),s.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function h(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function v(e){return u.all({public_holiday:1,contact_id:s.request.contact_id,from_date:{from:e},to_date:{to:e}}).then(function(e){return!!e.list.length})}function g(){return r.resolve()}function b(){return A(s.uiOptions.fromDate,"from").then(function(){return A(s.uiOptions.toDate,"to")})}function y(e){o.$watch(function(){return s.uiOptions.times[e].amount},function(e,t){s.isCalculationUnit("days")||+e==+t||(s.isRole("staff")&&(s.request.change_balance=!0),O(),s.performBalanceChangeCalculation())})}function _(e){var n=t(s.request[e+"_date"]).format("HH:mm"),a=s.uiOptions.times[e];(h(a.min,n)<=0||h(a.max,n)>=0)&&(n="from"===e?a.min:a.max),s.uiOptions.times[e].time=n}function q(){var e=s.uiOptions.multipleDays?["from","to"]:["from"],t=s.uiOptions.times;if(s.isCalculationUnit("hours"))return r.all(e.map(P)).then(function(){["from","to"].forEach(function(e){_(e),R(e),t[e].amount=Math.min(s.request[e+"_date_amount"],t[e].maxAmount).toString()}),s.uiOptions.multipleDays||s.updateEndTimeInputMinTime(s.uiOptions.times.from.time)}).then(O)}function $(){["from","to"].forEach(function(e){y(e),C(e)})}function C(e){o.$watch(function(){return s.uiOptions.times[e].time},function(t,n){s.isCalculationUnit("days")||t===n||(s.setRequestDateTimesAndDateTypes(),t&&R(e,!0))})}function A(e,t){return m(e,t).then(function(){s.loading[t+"DayTypes"]=!1})}function w(e){return A(s.uiOptions[e+"Date"],e).then(function(){if(s.isCalculationUnit("hours"))return P(e).then(function(){R(e,!0)})})}function P(e){var t=s.uiOptions[e+"Date"],n=!s.uiOptions.multipleDays;return t?s.request.getWorkDayForDate(s.convertDateToServerFormat(t)).then(function(t){x[e]=t,f(e,t),n&&"from"===e&&f("to",t)}).catch(function(t){return x[e]={},s.handleError(t)}).finally(function(){s.uiOptions.times[e].loading=!1,n&&(s.uiOptions.times.to.loading=!1)}):r.resolve()}function D(t){var n=s.uiOptions.times[t];s["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0"}function S(t,n){var a="request"+e.startCase(t)+"DayTypes";s[a]=n,s.isMode("create")&&(s.request[t+"_date_type"]=s[a][0].value)}function T(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?(s.disableAndShowLoadingTimeInput("from"),!s.uiOptions.multipleDays&&s.disableAndShowLoadingTimeInput("to"),P("from").then(function(){R("from",!0)})):r.resolve()}function R(e,t){var n=s.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,i=n.multipleDays&&"from"===a?r.max:n.times.to.time,u=x[a].number_of_hours?h(o,i).toString():"0";r.maxAmount=u,t&&(r.amount=r.maxAmount)}function O(){var e=s.uiOptions.times;s.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,s.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function I(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?P("from").then(function(){R("from",!0)}):r.resolve()}var x={};a.debug("RequestModalDetailsLeaveController"),s.calculateBalanceChange=c,s.canCalculateChange=l,s.canSubmit=d,s.initChildController=g,s.initDayTypesExtended=b,s.initTimesExtended=q,s.initWatchersExtended=$,s.onAbsenceTypeUpdateExtended=I,s.onDateChangeExtended=w,s.resetUIInputsExtended=D,s.setDaysSelectionModeExtended=T}n.controller("RequestModalDetailsLeaveController",a), +a.$inject=["$controller","$log","$q","$rootScope","detailsController","PublicHoliday","LeaveRequest"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s,i){function u(){return!(!i.canCalculateChange()||!i.request.sickness_reason)}function c(){return a.all([f(),h(),m(!0)])}function l(t){var n=i.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function d(t){return!!e.find(i.sicknessDocumentTypes,function(e){return e.value===t})}function f(){return s.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){i.sicknessDocumentTypes=e})}function m(t){return s.valuesOf("hrleaveandabsences_sickness_reason",t).then(function(t){i.sicknessReasons=e.indexBy(t,"name")})}function p(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1").on("crmUnload",function(){m(!1)})}function h(){i.showSicknessOptionsEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:i}),i.canSubmit=u,i.initChildController=c,i.isChecked=l,i.isDocumentInRequest=d,i.openSicknessReasonOptionsEditor=p}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","$rootScope","crmAngService","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return u.balance.change.amount=+u.request.toil_to_accrue,a.resolve(u.balance.change)}function l(){if(!u.request.from_date||!u.request.to_date)return u.uiOptions.max_toil_duration_and_accrual=null,void(u.uiOptions.toil_duration_in_hours=null);u.uiOptions.max_toil_duration_and_accrual=t.duration(t(u.request.to_date).diff(u.request.from_date)).asHours()}function d(){return v().catch(function(e){return e.length&&(u.errors=e),a.reject(e)}).then(function(e){return i.calculateToilExpiryDate(u.request.type_id,e)}).then(function(e){return u.request.toil_expiry_date=e,u.uiOptions.expiryDate=new Date(e),e})}function f(){return!!u.request.toil_to_accrue}function m(){var e=u.uiOptions.multipleDays&&!!u.request.to_date,t=!u.uiOptions.multipleDays&&!!u.request.from_date,n=t||e,a=F.from_date!==u.request.from_date||F.to_date!==u.request.to_date;return u.canDisplayToilExpirationField&&n&&H.hasExpirationFromAdminSettings&&a}function p(){return!!(u.request.from_date&&u.request.to_date&&u.request.toil_duration&&u.request.toil_to_accrue)}function h(){u.request.toil_expiry_date=!1,u.uiOptions.expiryDate=null}function v(){var e=u.uiOptions.multipleDays,t=u.request;return g({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function g(e){if(e.hasErrors){var n="Please select "+e.label+" to find expiry date";return a.reject([n])}return e.value?a.resolve(t(e.value).format("YYYY-MM-DD")):a.reject([])}function b(){var e=u.isMode("create")&&H.hasExpirationFromAdminSettings,t=H.hasPreviousExpirationDate,n=u.isLeaveType("toil"),a=u.canManage;u.canDisplayToilExpirationField=n&&(a||e||t)}function y(){u.uiOptions.toil_duration_in_hours=u.request.toil_duration/60}function _(){return H.hasPreviousExpirationDate=u.isMode("edit")&&!!u.request.toil_expiry_date,i.canExpire(u.request.type_id).then(function(e){H.hasExpirationFromAdminSettings=e})}function q(){return u.request.to_date_type=u.request.from_date_type="1",_().then(b).then($).then(S)}function $(){u.canManage&&(u.uiOptions.expiryDate=u.convertDateFormatFromServer(u.request.toil_expiry_date))}function C(){r.$watch(function(){return u.request.toil_to_accrue},function(e,t){+e!=+t&&u.performBalanceChangeCalculation()})}function A(){r.$watch(function(){return u.uiOptions.toil_duration_in_hours},function(e,t){e!==t&&u.isCalculationUnit("hours")&&I(),u.request.toil_duration=u.uiOptions.toil_duration_in_hours?60*u.uiOptions.toil_duration_in_hours:null})}function w(){var e=u.uiOptions.times;e.from.time=t(u.request.from_date).format("HH:mm"),e.to.time=t(u.request.to_date).format("HH:mm"),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time)}function P(){["from","to"].forEach(function(e){r.$watch(function(){return u.uiOptions.times[e].time},function(e,t){e!==t&&(u.setRequestDateTimesAndDateTypes(),B(),l(),x())})})}function D(){u.isMode("view")||(C(),A(),P())}function S(t){return s.valuesOf("hrleaveandabsences_toil_amounts",t).then(function(t){u.toilAmounts=e.sortBy(t,function(e){return+e.weight})})}function T(){return l(),x(),B()}function R(){return L(),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time),l(),U?U=!1:x(),B()}function O(e){u.uiOptions.times[e].time=""}function I(){u.request.toil_to_accrue=u.uiOptions.toil_duration_in_hours}function x(){u.uiOptions.toil_duration_in_hours=u.uiOptions.max_toil_duration_and_accrual}function E(){F=e.cloneDeep(u.request.attributes())}function L(){u.uiOptions.multipleDays?["from","to"].forEach(function(e){u.uiOptions.times[e].min="00:00",u.uiOptions.times[e].max="23:45"}):(u.uiOptions.times.from.min="00:00",u.uiOptions.times.from.max="23:30",u.uiOptions.times.to.min="00:15",u.uiOptions.times.to.max="23:45")}function M(){u.setRequestDateTimesAndDateTypes(),l(),x(),u.isCalculationUnit("hours")?I():u.request.toil_to_accrue=null}function k(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1").on("crmUnload",function(){S(!1)})}function j(){u.showTOILAccrualsOptionEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}function B(){return m()?d().catch(a.resolve):a.resolve()}function N(){u.uiOptions.expiryDate&&(u.request.toil_expiry_date=u.convertDateToServerFormat(u.uiOptions.expiryDate))}n.debug("RequestModalDetailsToilController");var F,U=!u.isMode("create"),H={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};u.canDisplayToilExpirationField=!1,u.calculateBalanceChange=c,u.canCalculateChange=f,u.canSubmit=p,u.clearExpiryDate=h,u.initChildController=q,u.initTimesExtended=w,u.initWatchersExtended=D,u.onAbsenceTypeUpdateExtended=M,u.onDateChangeExtended=T,u.openToilInDaysAccrualOptionsEditor=k,u.resetUIInputsExtended=O,u.setDaysSelectionModeExtended=R,u.updateExpiryDate=N,function(){E(),L(),j(),!u.isMode("create")&&y()}()}n.controller("RequestModalDetailsToilController",a),a.$inject=["$log","$q","$rootScope","crmAngService","OptionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function f(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function m(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,m(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,m(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),f.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={from_date_amount:0,to_date_amount:0,request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,f,m,p,h,v,g,b,y,_,q,$,C){function A(e){"days"===Le.selectedAbsenceType.calculation_unit_name?delete Le.request[e+"_date_amount"]:delete Le.request[e+"_date_type"]}function w(){["from","to"].forEach(A)}function P(){var e=Le.requestStatuses[_.statusNames.awaitingApproval].value;Te.status_id===e&&e!==Le.request.status_id&&d.publish("ManagerBadge:: Update Count")}function D(){return Ee.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return Ee.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function T(){return!Le.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function R(){var e=D();return Le.isMode("edit")&&(e=e&&(V()||S())),Le.canManage&&Le.requestStatuses&&(e=e&&!!Le.getStatusFromValue(Le.newStatusOnSave)),(e=e&&!!Le.period.id)&&!Le.isMode("view")}function O(){Le.isSelfRecord?Le.request.status_id=Le.requestStatuses[_.statusNames.awaitingApproval].value:Le.canManage&&(Le.request.status_id=Le.newStatusOnSave||Le.request.status_id)}function I(){if(Le.isMode("edit")&&!Le.isRole("staff")&&"toil"!==F())return Le.request.calculateBalanceChange(Le.selectedAbsenceType.calculation_unit_name).then(function(e){if(+Le.balance.change.amount!=+e.amount)return C.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function x(){Le.errors=[]}function E(){return Le.request.create().then($e).then(function(){me("LeaveRequest::new")})}function L(){ee()&&!Le.isRole("staff")&&(Le.request.change_balance=!0)}function M(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return Le.request.delete().then(function(){Le.dismissModal(),d.publish("LeaveRequest::delete",Le.request)})}})}function k(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(Le.getStatusFromValue(Le.request.status_id).name)}function N(e){return n.map(De[e],function(e){return Le.requestStatuses[e]})}function F(){return Le.request?Le.request.request_type:Le.leaveType||null}function U(){return!Le.request||e.equals({},Le.requestStatuses)?[]:Le.request.status_id?B():N("none")}function H(e){return n.find(Le.requestStatuses,function(t){return t.value===e})}function W(e){Le.errors=n.isArray(e)?e:[e],Le.loading.absenceTypes=!1,Le.submitting=!1}function V(){return!e.equals(Te,Le.request.attributes())||Le.canManage&&Le.newStatusOnSave}function G(){return Le.postContactSelection=!0,Le.staffMemberSelectionComplete=!1,Le.request.contact_id?r.resolve().then(ie).then(ue).then(he).then(ge).then(Z).then(z).then(Le.isMode("edit")?be:n.noop).then(function(){Le.postContactSelection=!1,Le.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Ie)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];De.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],De.awaiting_approval=e,De.more_information_required=e,De.rejected=e,De.approved=e,De.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return Le.canManage?m.find(Le.request.contact_id).then(function(e){Le.contactName=e.display_name}):r.resolve()}function X(){Re.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(he).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",Le.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){W(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){Se++})),s.$on("$destroy",Ce),s.$on("LeaveRequestPopup::addTab",function(e,t){Ee.push(t)})}function J(){var e,t;Le.request=Le.leaveRequest||null,e=F(),t=Le.initRequestAttributes(),"leave"===e?Le.request=y.init(t):"sickness"===e?Le.request=q.init(t):"toil"===e&&(Le.request=$.init(t))}function K(){var e={};return Le.request?e=Le.request.attributes():Le.canManage||(e={contact_id:Oe}),e}function Q(){if(xe="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(xe="admin")}).then(function(){return"staff"===xe&&u(_.permissions.ssp.manage).then(function(e){e&&(xe="manager")})}).finally(function(){Le.canManage=Le.isRole("manager")||Le.isRole("admin")})}function Z(){(Le.isRole("admin")||Le.isMode("create")&&Le.isRole("manager"))&&(Le.newStatusOnSave=Le.requestStatuses[_.statusNames.approved].value)}function ee(){return!Le.request.status_id||!n.includes(["cancelled","rejected"],H(Le.request.status_id).name)}function te(e){var t=Le.getStatusFromValue(Le.request.status_id);return!!t&&t.name===e}function ne(e){return Le.request&&Le.request.request_type===e}function ae(e){return Le.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date,"day")&&r.isSameOrBefore(t.end_date,"day")}function oe(e){return xe===e}function se(){return h.all().then(function(e){Le.absencePeriods=e})}function ie(){return v.all(j()).then(v.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return Le.loading.entitlements=!0,g.all({contact_id:Le.request.contact_id,period_id:Le.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){Le.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Oe=e.contactId})}function le(){return Le.selectedContactId?m.find(Le.selectedContactId).then(function(e){Le.managedContacts=[e]}):Le.isRole("admin")?m.all().then(function(e){Le.managedContacts=n.remove(e.list,function(e){return e.id!==Oe})}):m.find(Oe).then(function(e){return e.leaveManagees()}).then(function(e){Le.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){Le.requestStatuses=n.indexBy(e,"name")})}function fe(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function me(e){P(),d.publish(e,Le.request),Le.errors=[],Le.dismissModal()}function pe(){["from","to"].forEach(function(e){Le.request[e+"_date"]=Te[e+"_date"]})}function he(e){if(Le.absenceTypes=fe(Pe.types,e),!Le.absenceTypes.length)return r.reject(Ie)}function ve(){Le.period=n.find(Le.absencePeriods,function(e){return Le.isMode("create")?e.current:re(Le.request,e)})}function ge(){Le.isMode("create")?(Le.selectedAbsenceType=Le.absenceTypes[0],Le.request.type_id=Le.selectedAbsenceType.id):Le.selectedAbsenceType=n.find(Le.absenceTypes,function(e){return e.id===Le.request.type_id})}function be(){Te=e.copy(Le.request.attributes())}function ye(){var e;Le.request.id?(e=[Le.requestStatuses[_.statusNames.approved].value,Le.requestStatuses[_.statusNames.adminApproved].value,Le.requestStatuses[_.statusNames.rejected].value,Le.requestStatuses[_.statusNames.cancelled].value],Le.mode="edit",Le.isRole("staff")&&e.indexOf(Le.request.status_id)>-1&&(Le.mode="view")):Le.mode="create"}function _e(){var e=Le.request.status_id;if(!Le.isMode("view")&&!Le.submitting)return Le.submitting=!0,O(),w(),Le.request.isValid().then(ee()&&I).then(L).then(!Le.request.change_balance&&pe).then(qe).then(function(){return Le.isMode("edit")?we():E()}).catch(function(t){Le.request.status_id=e,t&&W(t)}).finally(function(){Le.submitting=!1})}function qe(){return r.all(Ee.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===Se&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return Se>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function Ce(){Re.forEach(function(e){e()})}function Ae(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function we(){return Le.request.update().then($e).then(function(){Le.isRole("manager")?me("LeaveRequest::updatedByManager"):(Le.isRole("staff")||Le.isRole("admin"))&&me("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,De={},Se=0,Te={},Re=[],Oe="",Ie="No entitlement",xe="",Ee=[],Le=n.assign(this,f);Le.absencePeriods=[],Le.absenceTypes=[],Le.canManage=!1,Le.contactName=null,Le.errors=[],Le.loading={absenceTypes:!0,entitlements:!0},Le.managedContacts=[],Le.mode="",Le.newStatusOnSave=null,Le.period={},Le.postContactSelection=!1,Le.requestStatuses={},Le.selectedAbsenceType={},Le.staffMemberSelectionComplete=!1,Le.submitting=!1,Le.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},Le.canChangeAbsenceType=T,Le.canSubmit=R,Le.closeAlert=x,Le.deleteLeaveRequest=M,Le.dismissModal=k,Le.getStatuses=U,Le.getStatusFromValue=H,Le.initAfterContactSelection=G,Le.initRequestAttributes=K,Le.isLeaveStatus=te,Le.isLeaveType=ne,Le.isMode=ae,Le.isRole=oe,Le.submit=_e,Le.updateAbsenceType=Ae,function(){Le.loading.absenceTypes=!0,Y(),X(),r.all([ce(),Q(),se(),de()]).then(J).then(ye).then(ve).then(function(){return Le.canManage&&!Le.isMode("edit")&&le()}).then(function(){if(Le.selectedContactId&&(Le.request.contact_id=Le.selectedContactId),Le.request.contact_id)return Le.initAfterContactSelection()}).catch(W).finally(function(){Le.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}}, +format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/manager-leave/modules/components",["common/angular"],function(e){return e.module("manager-leave.components",[])}),define("leave-absences/manager-leave/components/manager-leave-container",["leave-absences/manager-leave/modules/components"],function(e){e.component("managerLeaveContainer",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/manager-leave-container.html"}],controller:["$log","$rootScope","$state",function(e,t,n){function a(){n.go(r.tabName)}e.debug("Component: manager-leave-container"),t.section="manager-leave";var r=this;r.tabName=n.current.name,r.changeTab=a}],controllerAs:"managerLeave"})}),function(e){define("leave-absences/manager-leave/modules/settings",["common/angular"],function(t){return t.module("manager-leave.settings",[]).constant("settings",{debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/manager-leave/"})})}(CRM),function(e){define("leave-absences/manager-leave/modules/config",["common/angular","leave-absences/manager-leave/modules/settings"],function(t){return t.module("manager-leave.config",["manager-leave.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(t,n,a,r,o,s){o.debugEnabled(s.debug),n.defaults.stripTrailingSlashes=!1,r.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",a.otherwise("/manager-leave/requests"),t.state("manager-leave",{abstract:!0,url:"/manager-leave",template:'',resolve:{contactId:function(){return e.vars.leaveAndAbsences.contactId},format:["DateFormat",function(e){return e.getDateFormat()}]}}).state("manager-leave.requests",{url:"/requests?leave-request-id",template:'',onEnter:["$stateParams","LeavePopup",function(e,t){e["leave-request-id"]&&t.openModalByID(e["leave-request-id"])}]}).state("manager-leave.calendar",{url:"/calendar",template:''}).state("manager-leave.leave-balances",{url:"/leave-balances",template:""})}])})}(CRM),define("leave-absences/manager-leave/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/loading","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/modules/dialog","common/services/angular-date/date-format","common/services/check-permissions","common/services/crm-ang.service","leave-absences/shared/ui-router","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/components/leave-balance-tab.component","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/manage-leave-requests.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/services/leave-popup.service","leave-absences/manager-leave/components/manager-leave-container","leave-absences/manager-leave/modules/config"],function(e){return e.module("manager-leave",["ngResource","ngAnimate","ui.bootstrap","ui.router","ui.select","textAngular","common.angularDate","common.dialog","common.filters","common.models","common.directives","common.mocks","leave-absences.models","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","manager-leave.config","manager-leave.components"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/manager-leave":n+"/manager-leave"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/manager-leave/app","leave-absences/shared/models/leave-request.model"],function(e){e.bootstrap(document.querySelector("[data-leave-absences-manager-leave]"),["manager-leave"])})})}(CRM,require),define("manager-leave",function(){}); //# sourceMappingURL=/sites/all/modules/civicrm/tools/extensions/civihr/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/manager-leave.js.map \ No newline at end of file diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/my-leave.min.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/my-leave.min.js index c7c7261a4b2..4bd133e0174 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/my-leave.min.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/my-leave.min.js @@ -6,8 +6,9 @@ */ -!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return V(new(V(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[f]),c[r[f]]=e[r[f]]);return V({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))v.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&m(u[e],e)}),v.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var h=s(u||{}),v=[],g=[],b={};return H(u,m),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),m.$$values=b,m.$$promises=m.$$promises||!0,delete m.$$inheritedValues,c.resolve(b))}function u(e){m.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),m=c.promise,g=m.$$promises={},b=V({},a),y=1+v.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),m;o.$$inheritedValues&&r(b,f(o.$$inheritedValues,h)),V(g,o.$$promises),o.$$values?(_=r(b,f(o.$$values,h)),m.$$inheritedValues=f(o.$$values,h),i()):(o.$$inheritedValues&&(m.$$inheritedValues=f(o.$$inheritedValues,h)),o.then(i,u));for(var q=0,$=v.length;q<$;q+=3)a.hasOwnProperty(v[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(m.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),f=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(f++,g[e].then(function(t){b[e]=t,--f||l()},c))}),f||l(),g[n]=d.promise}(v[q],v[q+1],v[q+2]);return m}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(v.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(h[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return h[t]=new Y.Param(t,n,a,r),h[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(f,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=V({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",f=0,m=this.segments=[],p=r?r.params:{},h=this.params=r?r.params.$$new():new Y.ParamSet,v=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),m.push(g.segment),f=c.lastIndex;y=e.substring(f);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,f+_),q.length>0)for(f=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),f=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",m.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=m[0],this.$$paramNames=v}function y(e){V(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:h,caseInsensitive:f}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){V(this,e||{})}Y=this;var d,f=!1,h=!0,v=!1,g={},q=!0,$=[],w={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(f=e),f},this.strictMode=function(e){return j(e)&&(h=e),h},this.defaultSquashPolicy=function(e){if(!j(e))return v;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return v=e,e},this.compile=function(e,t){return new b(e,V(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(V({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(w,function(e,t){g[t]=new y(V({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(w,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!h.type.is(e))throw new Error("Default value ("+e+") for parameter '"+h.id+"' is not an instance of Type ("+h.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(m(h.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?h.type.$normalize(e):c()}function f(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var h=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return V(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return v;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),m(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);V(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:f})},l.prototype={$$new:function(){return a(this,V(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return m(r,t.self);for(var o in S)B(S[o])&&(t[o]=S[o](t,S.$delegates[o]));return P[n]=t,!t[R]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){A.$current.navigable==t&&c(e,n)||A.transitionTo(t,e,{inherit:!0,location:!1})}]),v(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=A.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=L[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.$current=t,A.current=t.self,A.params=n,W(A.params,m),A.transition=null,o.location&&t.navigable&&v.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),v.update(!0),A.current)}).then(null,function(a){return a===D?S:A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||v.update(),r.reject(a))});return B},A.is=function(e,t,a){a=V({relative:A.$current},a||{});var r=f(e,a.relative);return j(r)?A.$current===r&&(!t||c(r.params.$$values(t),m)):n},A.includes=function(e,t,a){if(a=V({relative:A.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=A.$current.name}var r=f(e,a.relative);if(!j(r))return n;if(!j(A.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(f&&(f.remove(),f=null),p&&(p.$destroy(),p=null),m){var e=m.data("$uiViewAnim");b.leave(m,function(){e.$$animLeave.resolve(),f=null}),f=m,m=null}}function d(s){var d,f=D(n,c,i,r),y=f&&e.$current&&e.$current.locals[f];if(s||y!==h){d=n.$new(),h=e.$current.locals[f],d.$emit("$viewContentLoading",f);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});m=_,p=d,p.$emit("$viewContentLoaded",f),p.$eval(v)}}var f,m,p,h,v=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=D(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var f=t.extend({},d);o[d.$$resolveAs]=f;var m=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=f),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}m(o)}}}}}function D(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function R(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function S(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function T(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function I(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function x(e,t){return{relative:S(e)||t.$current,inherit:!0}}function O(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=R(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=T(r),d=s[1]||s[0],f=null;c.options=V(x(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var m=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),f&&f(),d&&(f=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&m(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),m(),l.clickable&&(i=I(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function L(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){f.state=t[0],f.params=t[1],f.options=t[2],f.href=e.href(f.state,f.params,f.options),m&&m(),c&&(m=c.$$addStateInfo(f.state,f.params)),f.href&&r.$set(u.attr,f.href)}var i,u=T(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",f={state:null,params:null,options:null,href:null},m=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=I(a,e,t,u,function(){return f}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function k(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,S(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return h.push(u),v[s]=r,function(){var e=h.indexOf(u);-1!==e&&h.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function M(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function E(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,V=t.extend,W=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),v.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",v),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,V(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;a=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,n){function a(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(n.remainder=a[0].remainder),delete n["api.LeavePeriodEntitlement.getremainder"],n}function r(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return n.value=a,delete n["api.LeavePeriodEntitlement.getentitlement"],n}return e.debug("EntitlementAPI"),n.extend({all:function(t,n){return e.debug("EntitlementAPI.all"),t["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},n&&(t["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",t,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r),n&&(e=e.map(a)),e})},breakdown:function(t){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",t).then(function(e){return e.values})},getLeaveBalances:function(t,n,a,r,o){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",t,n,a,r,"getLeaveBalances",o)}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function f(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function m(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,m(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,m(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),f.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,t,n){function a(n,a,r,o,s,i){function u(){return d().then(function(n){var a=n.filter(function(e){var n=e.info.details;return t(n.period_start_date).isSameOrBefore(v.selectedPeriod.end_date)&&(t(n.period_end_date).isSameOrAfter(v.selectedPeriod.start_date)||!n.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function c(){return{loadContacts:function(){var e=v.filters.userSettings.assignedTo.type;return f(e).then(function(e){v.lookupContacts=e}).then(function(){return"me"!==e?u():a.resolve(null)}).then(function(e){return v.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return r.all(m(),null,"display_name").then(function(e){return e.list})}function d(){return h?a.resolve(h):s.all()}function f(e){return"me"===e?r.leaveManagees(v.contactId):"unassigned"===e?r.leaveManagees(void 0,{unassigned:!0}):r.all().then(function(e){return e.list})}function m(){return{department:v.filters.userSettings.department?v.filters.userSettings.department.value:null,level_type:v.filters.userSettings.level_type?v.filters.userSettings.level_type.value:null,location:v.filters.userSettings.location?v.filters.userSettings.location.value:null,region:v.filters.userSettings.region?v.filters.userSettings.region.value:null,id:{IN:v.filters.userSettings.contact?[v.filters.userSettings.contact.id]:v.lookupContacts.map(function(e){return e.id})}}}function p(e){i.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,f){function m(){for(var e=[],t=n(L.selectedPeriod.start_date).clone().startOf("month"),a=n(L.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");L.months=e}function p(){s.$new().$watch(function(){return L.selectedMonths},function(t,n){null===n||e.equals(t,n)||R()})}function h(e){L.injectMonths=!0,I("injected").then(function(){R(e)}).then(function(){L.loading.calendar=!1})}function v(){x=a("LeaveCalendar"+t.capitalize(O)+"Controller").init(L)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){L.absencePeriods=t.sortBy(e,"start_date"),L.selectedPeriod=t.find(L.absencePeriods,function(e){return!!e.current})}).then(m).then(S)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return x.loadContacts().then(function(e){L.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){L.filters.optionValues.regions=e.hrjc_region,L.filters.optionValues.locations=e.hrjc_location,L.filters.optionValues.levelTypes=e.hrjc_level_type,L.filters.optionValues.departments=e.hrjc_department})}function w(){return l.all()}function C(){return r.all([y(),w(),_()]).then(function(e){L.supportData.absenceTypes=e[0],L.supportData.publicHolidays=e[1],L.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,L.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,L.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,L.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function A(){var e=r.resolve();return L.injectMonths&&(e=I("destroyed"),L.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function D(e){ -e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){L.loading.calendar=!0}).then(A).then("period"===e?m:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function R(e){var n=L.selectedMonths.length?L.months.filter(function(e){return t.includes(L.selectedMonths,e.index)}):L.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function S(){L.selectedMonths=[n().month()]}function T(){return L.roleOverride?r.resolve().then(function(){O=L.roleOverride}):r.all([f(i.permissions.admin.administer),f(i.permissions.ssp.manage)]).then(function(e){O=e[0]?"admin":e[1]?"manager":"staff"})}function I(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===L.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var x,O,L=this;L.absencePeriods=[],L.contacts=[],L.contactIdsToReduceTo=null,L.injectMonths=!1,L.months=[],L.selectedMonths=null,L.selectedPeriod=null,L.showContactName=!1,L.showFilters=!1,L.supportData={},L.loading={calendar:!0,page:!0},L.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},L.labelPeriod=g,L.refresh=D,function(){T().then(p).then(v).then(A).then(b).then(function(){return r.all([q(),C()])}).then(function(){return L.showFilters?$():t.noop}).then(function(){h()}).then(function(){L.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r){"use strict";function o(){_.calculationUnit=s(_.supportData.calculationUnits,"value",g.calculation_unit)}function s(t,n,a){return e.find(t,function(e){return+e[n]==+a})}function i(){var e,n;return n=t(_.contactData.leaveRequest.from_date).isSame(_.contactData.leaveRequest.to_date,"day"),e=n?"single-date":"multiple-dates","type-"+_.calculationUnit.name+"-on-"+e+"-tooltip"}function u(){g=s(_.supportData.absenceTypes,"id",_.contactData.leaveRequest.type_id),_.contactData.leaveRequest["type_id.title"]=g.title}function c(){"days"===_.calculationUnit.name&&(b=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.from_date_type),y=s(_.supportData.dayTypes,"value",_.contactData.leaveRequest.to_date_type),_.contactData.leaveRequest["from_date_type.label"]=b.label,_.contactData.leaveRequest["to_date_type.label"]=y.label)}function l(e,t,n,a,o){e.stopPropagation(),r.openModal(t,n,a,o)}function d(){_.dates.from=new Date(_.contactData.leaveRequest.from_date),_.dates.to=new Date(_.contactData.leaveRequest.to_date)}function f(){_.contactData.isAccruedTOIL?_.label="AT":"days"===_.calculationUnit.name?m():p()}function m(){_.label=_.contactData.isAM?"AM":_.contactData.isPM?"PM":""}function p(){var e=t(_.contactData.leaveRequest.from_date).isSame(_.date,"day"),n=t(_.contactData.leaveRequest.to_date).isSame(_.date,"day");_.label=e?t(_.contactData.leaveRequest.from_date).format("HH:mm"):n?t(_.contactData.leaveRequest.to_date).format("HH:mm"):""}function h(){_.tooltipTemplate=_.contactData.isAccruedTOIL?"accrued-toil-tooltip":i()}function v(){a.$watch("day.contactData.leaveRequest",function(){_.contactData&&_.contactData.leaveRequest&&(u(),o(),c(),f(),d(),h())})}n.debug("Component: leave-calendar-day");var g,b,y,_=this;_.calculationUnit="",_.dates={from:null,to:null},_.label="",_.tooltipTemplate=null,_.openLeavePopup=l,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){y([e]),B(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(V.period.start_date)&&r.isSameOrBefore(V.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function f(e){return U[e]}function m(){return V.showOnlyWithLeaveRequests?V.contacts.filter(function(e){return Object.keys(H[e.id]||{}).length}):V.contacts}function p(e){return t(e,u.serverDateFormat)}function h(e){x(e),B(e)}function v(e){return CRM.url("civicrm/contact/view",{cid:e})}function g(){return V.contactIdsToReduceTo&&(V.contacts=V.contacts.filter(function(t){return e.includes(V.contactIdsToReduceTo,t.contact_id)||e.find(H,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function b(){V.supportData.dayTypes=e.indexBy(V.supportData.dayTypes,"name"),V.supportData.leaveRequestStatuses=e.indexBy(V.supportData.leaveRequestStatuses,"value"),V.supportData.publicHolidays=e.transform(V.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function y(e){return e.forEach(function(e){var t=A(e);H[e.contact_id]=H[e.contact_id]||{},t.forEach(function(t){H[e.contact_id][t.date]=e})}),a.resolve()}function _(){F.push(r.$on("LeaveCalendar::showMonths",M)),F.push(i.subscribe("LeaveRequest::new",c)),F.push(i.subscribe("LeaveRequest::edit",j)),F.push(i.subscribe("LeaveRequest::updatedByManager",j)),F.push(i.subscribe("LeaveRequest::delete",h)),F.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):j(e.leaveRequest)}))}function q(e,n,a){var r=V.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function $(e,t){return e.request_type===t}function w(e){return!!V.supportData.publicHolidays[p(e).valueOf()]}function C(t){var n=V.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function A(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===V.month.index&&r.year()===V.month.year&&a.push(e.find(V.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function P(t){return e.find(H[t.contact_id],function(e){return t.id===e.id})}function D(t){var n=e.find(V.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function R(){return[D(u.statusNames.approved),D(u.statusNames.adminApproved),D(u.statusNames.awaitingApproval),D(u.statusNames.moreInformationRequired)]}function S(){return V.month.loading=!0,a.all([I(),T()]).then(g).then(k).then(function(){N=!0}).then(function(){V.month.loading=!1})}function T(){return s.all({from_date:{to:V.month.days[V.month.days.length-1].date},to_date:{from:V.month.days[0].date},status_id:{IN:R()},contact_id:{IN:V.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(V.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return y(e.list)})}function I(){var t=V.month.days[0].date,n=V.month.days[V.month.days.length-1].date;return o.get(V.contacts.map(function(e){return e.id}),t,n).then(function(t){U=e.indexBy(t,"contact_id")})}function x(t){H[t.contact_id]=e.omit(H[t.contact_id],function(e){return e.id===t.id})}function O(){r.$emit("LeaveCalendar::monthDestroyed"),F.map(function(e){e.remove?e.remove():e()})}function L(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=f(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:w(t.date)})}),o.then(function(){return H[n]?H[n][t.date]:null}).then(function(a){e.assign(t.contactsData[n],{leaveRequest:a||null,styles:a?E(a):null,isAccruedTOIL:a?$(a,"toil"):null,isRequested:a?C(a):null,isAM:a?q("half_day_am",a,t.date):null,isPM:a?q("half_day_pm",a,t.date):null})})}function k(){return a.all(V.month.days.map(function(e){return a.all(V.contacts.map(function(t){return L(e,t.id)}))}))}function M(t,n,a){!e.find(n,function(e){return e.index===V.month.index})?V.visible=!1:(V.currentPage=0,V.visible=!0,(a||!N)&&S())}function E(t){var n=e.find(V.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function j(e){var t=P(e);t&&(h(t),-1!==R().indexOf(e.status_id)&&c(e))}function B(e){return a.all(A(e).map(function(t){return L(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var N=!1,F=[],U={},H={},V=this;V.currentPage=0,V.pageSize=20,V.visible=!1,V.showContactName=!!V.showContactName,V.showOnlyWithLeaveRequests=!!V.showOnlyWithLeaveRequests,V.$onDestroy=O,V.contactsList=m,V.getContactUrl=v,function(){var e=t().month(V.month.index).year(V.month.year);b(),_(),V.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o,promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(h(t)):m(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function f(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||!!e.includes([$.awaitingApproval,$.moreInformationRequired],n)&&("manager"===q.role||("3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a))}function m(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=w[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function v(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(w,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!f(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:w[e].label,isDirectAction:w[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,w={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function f(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function m(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=f,q.getActiveComments=m,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,f,m){function p(){pe.balance.closing=pe.balance.opening+pe.balance.change.amount}function h(e){return t(e,u.serverDateFormat).toDate()}function v(e){return t(e).format(u.serverDateFormat)}function g(e){var t;return s.resolve().then(function(){X(e),"from"===e&&K(),B("hours")&&(_(e),"from"!==e||pe.uiOptions.multipleDays||_("to")),pe.loading[e+"DayTypes"]=!0}).then(pe.onDateChangeExtended).then(function(){return w(e)}).then(function(e){if(t=e.id!==pe.period.id,t&&(pe.period=e),!pe.period.id)return s.reject("Please change date as it is not in any absence period")}).then(Z).then(function(){if(t)return W()}).then(function(){return U(pe.uiOptions[e+"Date"],e)}).then(function(){if(B("hours"))return V(e).then(function(){ne(e,!0)})}).then(function(){if(oe(),!t)return Y();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(S)}function b(){return oe(),Y()}function y(){return pe.uiOptions.toDate=null,X("to"),s.resolve().then(function(){if(B("hours")&&pe.uiOptions.fromDate)return _("from"),!pe.uiOptions.multipleDays&&_("to"),V("from").then(function(){ne("from",!0)}).then(oe)}).then(pe.setDaysSelectionModeExtended).then(!pe.uiOptions.multipleDays&&Y)}function _(e){var t=pe.uiOptions.times[e];t.loading=!0,t.disabled=!0}function q(t,n){var a=pe.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);pe.uiOptions.multipleDays||("from"===t&&o&&r&&(o=P(o).subtract(pe.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=P(r).add(pe.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min,a.disabled=!1}function $(t,n){return t?(t=v(t),d.isPublicHoliday(t).then(function(n){return n?pe.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):C(t,pe.requestDayTypes).then(function(t){return t.length?t:pe.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return te(n,e),e})):s.reject([])}function w(n){var a=t(pe.uiOptions[n+"Date"]).format(pe.uiOptions.userDateFormat.toUpperCase());return e.find(pe.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function C(e,n){return e=t(e),s.all([pe.calendar.isNonWorkingDay(e),pe.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function A(){return pe.request?pe.request.request_type:pe.leaveType||null}function P(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function D(){return ie(),pe.loading.balanceChange=!0,pe.request.getBalanceChangeBreakdown().then(Q).catch(S)}function R(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function S(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),pe.loading.fromDayTypes=!1,pe.loading.balanceChange=!1,pe.loading.tab=!1,pe.loading.toDayTypes=!1}function T(){return pe.isMode("create")||pe.forceRecalculateBalanceChange?Y():D()}function I(){var e=pe.request.attributes();return pe.uiOptions.fromDate=h(pe.request.from_date),U(pe.uiOptions.fromDate,"from").then(function(){return pe.request.to_date=e.to_date,pe.request.to_date_type=e.to_date_type,pe.uiOptions.toDate=h(pe.request.to_date),U(pe.uiOptions.toDate,"to")})}function x(e){o.$watch("detailsTab.uiOptions.times."+e+".amount",function(e,t){B("days")||+e==+t||(se(),pe.performBalanceChangeCalculation())})}function O(){me.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){ce()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){le(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",Y))}function L(){pe.isMode("edit")&&(pe.isLeaveStatus(u.statusNames.approved)||pe.isLeaveStatus(u.statusNames.adminApproved))&&(fe={absenceTypeId:pe.request.type_id,value:pe.selectedAbsenceType.remainder-pe.request.balance_change})}function k(e){var n=t(pe.request[e+"_date"]).format("HH:mm"),a=pe.uiOptions.times[e];(R(a.min,n)<=0||R(a.max,n)>=0)&&(n="from"===e?a.min:a.max),pe.uiOptions.times[e].time=n}function M(){var e=pe.uiOptions.multipleDays?["from","to"]:["from"],t=pe.uiOptions.times;return s.all(e.map(V)).then(function(){["from","to"].forEach(function(e){k(e),ne(e),t[e].amount=Math.min(pe.request[e+"_date_amount"],t[e].maxAmount).toString()}),pe.uiOptions.multipleDays||de(pe.uiOptions.times.from.time)}).then(se)}function E(){["from","to"].forEach(function(e){x(e),j(e)})}function j(e){o.$watch("detailsTab.uiOptions.times."+e+".time",function(t,n){B("days")||t===n||(oe(),t&&(!pe.uiOptions.multipleDays&&"from"===e&&de(t),ne(e,!0)))})}function B(e){return pe.selectedAbsenceType.calculation_unit_name===e}function N(e){return pe.request.request_type===e}function F(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function U(e,t){return $(e,t).then(function(){pe.loading[t+"DayTypes"]=!1})}function H(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){pe.requestDayTypes=e})}function V(e){var t=pe.uiOptions[e+"Date"],n=pe.uiOptions.times[e],a=!pe.uiOptions.multipleDays;return t?pe.request.getWorkDayForDate(v(t)).then(function(t){he[e]=t,q(e,t),a&&"from"===e&&q("to",t)}).catch(function(t){return he[e]={},S(t)}).finally(function(){n.loading=!1,a&&(pe.uiOptions.times.to.loading=!1)}):s.resolve()}function W(){return c.get(pe.request.contact_id,pe.period.start_date,pe.period.end_date).then(function(e){pe.calendar=e})}function G(){var e=(pe.pagination.currentPage-1)*pe.pagination.numPerPage,t=e+pe.pagination.numPerPage;pe.pagination.filteredbreakdown=pe.balance.change.breakdown.slice(e,t)}function Y(){return ie(),pe.canCalculateChange()?(pe.loading.balanceChange=!0,pe.request.change_balance=!0,pe.calculateBalanceChange().then(Q).catch(S).finally(function(){pe.loading.balanceChange=!1})):s.resolve()}function z(){pe.pagination.totalItems=pe.balance.change.breakdown.length,pe.pagination.filteredbreakdown=pe.balance.change.breakdown,pe.pagination.pageChanged()}function J(){return v(pe.request.from_date)===v(pe.request.to_date)}function K(){pe.uiOptions.toDate&&pe.uiOptions.fromDate&&pe.uiOptions.multipleDays&&t(pe.uiOptions.toDate).isSameOrBefore(pe.uiOptions.fromDate)&&(pe.uiOptions.toDate=null,X("to"))}function X(t){var n=pe.uiOptions.times[t];pe["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0",n.loading=!1,oe(),se(),ie()}function Q(e){pe.balance.change=e,pe.request.balance_change=e.amount,p(),z(),pe.loading.balanceChange=!1}function Z(){var e,n,a;pe.uiOptions.fromDate?(e=t(pe.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=h(pe.period.start_date),n=pe.uiOptions.date.to.options.minDate),pe.uiOptions.date.to.options.initDate=n,pe.uiOptions.date.to.options.minDate=a,pe.uiOptions.date.to.options.maxDate=h(pe.period.end_date)}function ee(){return!pe.isMode("create")&&J()||pe.isMode("create")&&(N("sickness")||B("hours"))?pe.uiOptions.multipleDays=!1:pe.uiOptions.multipleDays=!0,s.resolve().then(pe.setDaysSelectionModeExtended)}function te(t,n){var a="request"+e.startCase(t)+"DayTypes";pe[a]=n,pe.isMode("create")&&(pe.request[t+"_date_type"]=pe[a][0].value)}function ne(e,t){var n=pe.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,s=n.multipleDays&&"from"===a?r.max:n.times.to.time,i=he[a].number_of_hours?R(o,s).toString():"0";r.maxAmount=i,t&&(r.amount=r.maxAmount)}function ae(){fe&&fe.absenceTypeId===pe.selectedAbsenceType.id?pe.balance.opening=fe.value||0:pe.balance.opening=pe.selectedAbsenceType.remainder}function re(){pe.selectedAbsenceType=e.find(pe.absenceTypes,function(e){return e.id===pe.request.type_id})}function oe(){var e=pe.uiOptions,t=e.times;pe.request.from_date=e.fromDate?v(e.fromDate):null,pe.request.to_date=e.toDate?v(e.toDate):null,!e.multipleDays&&e.fromDate&&(pe.request.to_date=pe.request.from_date,pe.request.to_date_type=pe.request.from_date_type),B("hours")&&!N("toil")&&(pe.request.from_date=pe.request.from_date&&t.from.time?pe.request.from_date+" "+t.from.time:null,pe.request.to_date=pe.request.to_date&&t.to.time?pe.request.to_date+" "+t.to.time:null)}function se(){var e=pe.uiOptions.times;pe.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,pe.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function ie(){pe.uiOptions.showBalance=pe.canCalculateChange()}function ue(){e.forEach(me,function(e){e()})}function ce(){var e,t=pe.selectedAbsenceType.calculation_unit_name;return re(),e=t!==pe.selectedAbsenceType.calculation_unit_name,ae(),s.resolve().then(e&&ee).then(function(){if(e&&B("hours"))return V("from").then(function(){ne("from",!0)})}).then(e&&oe).then(Y)}function le(e){return pe.absenceTypes=e,re(),t(pe.uiOptions.toDate).isAfter(pe.period.end_date)&&(pe.uiOptions.toDate=void 0,X("to")),ae(),Y()}function de(e){var t=P(e).add(pe.uiOptions.time_interval,"minutes");t.isAfter(P(pe.uiOptions.times.to.max))||(pe.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(P(pe.uiOptions.times.to.time))&&(pe.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var fe=null,me=[],pe=this,he={};pe.canManage=!1,pe.calendar={},pe.errors=[],pe.isRequired=!0,pe.requestDayTypes=[],pe.statusNames=u.statusNames,pe.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},pe.pagination={currentPage:1,filteredbreakdown:pe.balance.change.breakdown,numPerPage:7,totalItems:pe.balance.change.breakdown.length,pageChanged:G},pe.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},pe.convertDateFormatFromServer=h,pe.convertDateToServerFormat=v,pe.dateChangeHandler=g,pe.dateTypeChangeHandler=b,pe.daysSelectionModeChangeHandler=y,pe.isLeaveType=N,pe.isNotWorkingDay=F,pe.performBalanceChangeCalculation=Y,pe.$onDestroy=ue,function(){n("RequestModalDetails"+e.capitalize(A(pe.leaveType,pe.request))+"Controller",{detailsController:pe}),pe.canManage=pe.isRole("manager")||pe.isRole("admin"),pe.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",pe),O(),pe.initChildController().then(function(){return s.all([W(),H()])}).then(!pe.isMode("create")&&I).then(ee).then(function(){if(!pe.isMode("create")&&B("hours"))return M().then(oe)}).then(!pe.isMode("create")&&Z).then(L).then(ae).then(T).then(function(){pe.isMode("view")||N("toil")||E()}).catch(S).finally(function(){pe.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","PublicHoliday","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return T.fileUploader&&T.fileUploader.queue.length>0}function f(){return T.getFilesAmount()0?D.map(function(e){return e.label}).join(", "):""}function q(){return T.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(D.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){S[e.label]=t})})).catch(function(){S=null})}function w(){return u.valuesOf("safe_file_extension").then(function(e){D=e})}function C(e){return!e.attachment_id||T.canManage}function A(){e.forEach(R,function(e){e()})}function P(e,t){T.fileUploader.queue&&T.fileUploader.queue.length>0?T.fileUploader.uploadAll({entityID:T.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var D=[],R=[],S={},T=Object.create(this);return T.filesLoaded=!1,T.fileUploader=null,T.today=Date.now(),T.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",T.userDateFormat=s.DATE_FORMAT,T.$onDestroy=A,T.canRemoveAttachment=C,T.canSubmit=d,T.canUploadMore=f,T.formatDateTime=m,T.getAuthorName=p,T.getFilesAmount=h,T.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",T),b(),a.all([w(),q()]).then(y).finally(function(){T.filesLoaded=!0})}(),T}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{ -type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"},{type:"toil",icon:"calendar-plus-o",label:"Overtime"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{btnClass:"@",contactId:"<",selectedContactId:"<",isSelfRecord:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/staff-leave-report.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(t,n,a,r,o,s,i,u,c,l,d,f){function m(e,t){t.data.push(e),t.dataIndex[e.id]=e}function p(e){E(e),H.sections.other.open&&m(e,H.sections.other)}function h(){Object.values(H.sections).forEach(function(e){e.data=[]})}function v(e){var t=U[e.status];t?t(e.leaveRequest):H.refresh()}function g(t){t.dataIndex=e.indexBy(t.data,"id")}function b(e){return e.current?"Current Period ("+e.title+")":e.title}function y(){return o.all().then(function(t){H.absencePeriods=e.sortBy(t,"start_date"),H.selectedPeriod=e.find(H.absencePeriods,function(e){return!0===e.current})})}function _(){return s.all().then(s.loadCalculationUnits).then(function(t){H.absenceTypes=t,H.absenceTypesIndexed=e.indexBy(t,"id")})}function q(){return D("approved",{status_id:F(f.statusNames.approved)})}function $(){return n.all([u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,null,!0),u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,[F(f.statusNames.approved)]),u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,[F(f.statusNames.awaitingApproval),F(f.statusNames.moreInformationRequired)])]).then(function(e){H.absenceTypes.forEach(function(t){t.balanceChanges={holidays:e[0][t.id],approved:e[1][t.id],pending:e[2][t.id]}})})}function w(){return i.all({contact_id:H.contactId,period_id:H.selectedPeriod.id},!0).then(function(e){H.entitlements=e}).then(function(){H.absenceTypesFiltered=H.absenceTypes.filter(function(t){var n=e.find(H.entitlements,function(e){return e.type_id===t.id});return t.entitlement=n?n.value:0,t.remainder=n?n.remainder:{current:0,future:0},!(0===t.entitlement&&"1"!==t.allow_overuse&&"1"!==t.allow_accruals_request)})})}function C(){return i.breakdown({contact_id:H.contactId,period_id:H.selectedPeriod.id},H.entitlements).then(function(){return L(H.entitlements)}).then(function(e){H.sections.entitlements.data=e})}function A(){return n.all([i.breakdown({contact_id:H.contactId,period_id:H.selectedPeriod.id,expired:!0}),P({request_type:"toil",expired:!0})]).then(function(e){return n.all({expiredBalanceChangesFlatten:L(e[0]),expiredTOILS:k(e[1].list)})}).then(function(t){H.sections.expired.data=t.expiredBalanceChangesFlatten.concat(t.expiredTOILS),H.sections.expired.data=e.sortBy(H.sections.expired.data,"expiry_date")})}function P(t){return u.all(e.assign({contact_id:H.contactId,from_date:{from:H.selectedPeriod.start_date},to_date:{to:H.selectedPeriod.end_date},type_id:{IN:H.absenceTypes.map(function(e){return e.id})}},t),null,"from_date ASC",null,!1)}function D(e,t){return P(t).then(function(t){H.sections[e].data=t.list})}function R(){return n.all(Object.values(H.sections).filter(function(e){return e.open}).map(x))}function S(){return D("other",{status_id:{in:[F(f.statusNames.rejected),F(f.statusNames.cancelled)]}})}function T(){return D("pending",{status_id:{in:[F(f.statusNames.awaitingApproval),F(f.statusNames.moreInformationRequired)]}})}function I(){return D("holidays",{public_holiday:!0})}function x(e){return e.loading=!0,e.loadLeaveRequests().then(g.bind(this,e)).then(function(){e.loading=!1})}function O(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(t){H.leaveRequestStatuses=e.indexBy(t,"value")})}function L(t){return n.resolve().then(function(){return t.map(function(t){var n=e.find(H.entitlements,function(e){return e.id===t.id});return t.breakdown.map(function(t){return e.assign(e.clone(t),{type_id:n.type_id})})})}).then(function(e){return Array.prototype.concat.apply([],e)})}function k(e){return n.resolve().then(function(){return e.map(function(e){return{expiry_date:e.toil_expiry_date,type:{label:"Accrued TOIL"}}})})}function M(){l.subscribe("LeaveRequest::new",function(){H.refresh()}),l.subscribe("LeaveRequest::edit",function(){H.refresh()}),l.subscribe("LeaveRequest::statusUpdate",v),l.subscribe("LeaveRequest::delete",function(e){E(e)})}function E(t){e.forEach(H.sections,function(n,a){n.dataIndex[t.id]&&(e.remove(n.data,function(e){return e.id===t.id}),delete n.dataIndex[t.id],j(t,a))})}function j(e,t){var n=H.absenceTypesIndexed[e.type_id],a="pending"===t?"future":"current";n.balanceChanges[t]-=e.balance_change,n.remainder[a]-=e.balance_change}function B(){H.loading.content=!0,n.all([w(),$()]).then(function(){H.loading.content=!1}).then(function(){return n.all([R(),h()])})}function N(e){var t=H.sections[e];t.open=!t.open,t.open&&!t.data.length&&x(t)}function F(t){return e.find(H.leaveRequestStatuses,function(e){return e.name===t}).value}t.debug("Component: staff-leave-report");var U={delete:E,cancel:p},H=this;H.absencePeriods=[],H.absenceTypes=[],H.absenceTypesFiltered=[],H.absenceTypesIndexed={},H.dateFormat=d.DATE_FORMAT,H.leaveRequestStatuses={},H.selectedPeriod=null,H.role="absence-tab"===a.section?"admin":"staff",H.loading={content:!0,page:!0},H.sections={approved:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:q},entitlements:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:C},expired:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:A},holidays:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:I},pending:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:T},other:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:S}},H.labelPeriod=b,H.refresh=B,H.toggleSection=N,function(){n.all([O(),_(),y()]).then(function(){H.loading.page=!1}).then(function(){return n.all([w(),$()])}).then(function(){H.loading.content=!1}),M()}()}n.component("staffLeaveReport",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/staff-leave-report.html"}],controllerAs:"report",controller:["$log","$q","$rootScope","checkPermissions","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","OptionGroup","pubSub","HR_settings","shared-settings",a]})}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["leave-absences/shared/modules/controllers"],function(e){function t(e,t,n,a){function r(){return a.request.calculateBalanceChange(a.selectedAbsenceType.calculation_unit_name)}function o(){var e=a.request,t=!!e.from_date&&!!e.to_date,n=a.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function s(){return a.canCalculateChange()}function i(){return n.resolve()}t.debug("RequestModalDetailsLeaveController"),a.calculateBalanceChange=r,a.canCalculateChange=o,a.canSubmit=s,a.initChildController=i}e.controller("RequestModalDetailsLeaveController",t),t.$inject=["$controller","$log","$q","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o){function s(){return!(!o.canCalculateChange()||!o.request.sickness_reason)}function i(){return a.all([l(),d()])}function u(t){var n=o.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function c(t){return!!e.find(o.sicknessDocumentTypes,function(e){return e.value===t})}function l(){return r.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){o.sicknessDocumentTypes=e})}function d(){return r.valuesOf("hrleaveandabsences_sickness_reason").then(function(t){o.sicknessReasons=e.indexBy(t,"name")})}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:o}),o.canSubmit=s,o.initChildController=i,o.isChecked=u,o.isDocumentInRequest=c}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s){function i(){return s.balance.change.amount=+s.request.toil_to_accrue,n.resolve(s.balance.change)}function u(){return m().catch(function(e){return e.length&&(s.errors=e),n.reject(e)}).then(function(e){return o.calculateToilExpiryDate(s.request.type_id,e)}).then(function(e){return s.request.toil_expiry_date=e,s.uiOptions.expiryDate=new Date(e),e})}function c(){return!!s.request.toil_to_accrue}function l(){var e=s.uiOptions.multipleDays&&!!s.request.to_date,t=!s.uiOptions.multipleDays&&!!s.request.from_date,n=t||e,a=C.from_date!==s.request.from_date||C.to_date!==s.request.to_date;return s.canDisplayToilExpirationField&&n&&A.hasExpirationFromAdminSettings&&a}function d(){return!!(s.request.from_date&&s.request.to_date&&s.request.toil_duration&&s.request.toil_to_accrue)}function f(){s.request.toil_expiry_date=!1,s.uiOptions.expiryDate=null}function m(){var e=s.uiOptions.multipleDays,t=s.request;return p({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function p(e){if(e.hasErrors){var t="Please select "+e.label+" to find expiry date";return n.reject([t])}return e.value?n.resolve(e.value):n.reject([])}function h(){var e=s.isMode("create")&&A.hasExpirationFromAdminSettings,t=A.hasPreviousExpirationDate,n=s.isLeaveType("toil"),a=s.canManage;s.canDisplayToilExpirationField=n&&(a||e||t)}function v(){return A.hasPreviousExpirationDate=s.isMode("edit")&&!!s.request.toil_expiry_date,o.canExpire(s.request.type_id).then(function(e){A.hasExpirationFromAdminSettings=e})}function g(){return s.request.to_date_type=s.request.from_date_type="1",v().then(h).then(b).then(_)}function b(){s.canManage&&(s.uiOptions.expiryDate=s.convertDateFormatFromServer(s.request.toil_expiry_date))}function y(){s.isMode("view")||a.$watch(function(){return s.request.toil_to_accrue},function(e,t){+e!=+t&&s.performBalanceChangeCalculation()})}function _(){return r.valuesOf("hrleaveandabsences_toil_amounts").then(function(t){s.toilAmounts=e.indexBy(t,"value")})}function q(){C=angular.copy(s.request.attributes())}function $(){return l()?u().catch(n.resolve):n.resolve()}function w(){s.uiOptions.expiryDate&&(s.request.toil_expiry_date=s.convertDateToServerFormat(s.uiOptions.expiryDate))}t.debug("RequestModalDetailsToilController");var C,A={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};s.canDisplayToilExpirationField=!1,s.calculateBalanceChange=i,s.canCalculateChange=c,s.canSubmit=d,s.clearExpiryDate=f,s.initChildController=g,s.onDateChangeExtended=$,s.setDaysSelectionModeExtended=$,s.updateExpiryDate=w,function(){y(),q()}()}t.controller("RequestModalDetailsToilController",n),n.$inject=["$log","$q","$rootScope","api.optionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={toilDurationHours:"0",toilDurationMinutes:"0",request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},transformAttributes:function(e){var t=Number(e.toil_duration);return t&&(e.toilDurationHours=Math.floor(t/60).toString(),e.toilDurationMinutes=(t%60).toString()),e},updateDuration:function(){this.toil_duration=60*Number(this.toilDurationHours)+Number(this.toilDurationMinutes)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files","toilDurationHours","toilDurationMinutes"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,f,m,p,h,v,g,b,y,_,q,$,w){function C(e){"days"===ke.selectedAbsenceType.calculation_unit_name?delete ke.request[e+"_date_amount"]:delete ke.request[e+"_date_type"]}function A(){["from","to"].forEach(C)}function P(){var e=ke.requestStatuses[_.statusNames.awaitingApproval].value;Se.status_id===e&&e!==ke.request.status_id&&d.publish("ManagerBadge:: Update Count")}function D(){return Le.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function R(){return Le.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return!ke.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function T(){var e=D();return ke.isMode("edit")&&(e=e&&(W()||R())),ke.canManage&&ke.requestStatuses&&(e=e&&!!ke.getStatusFromValue(ke.newStatusOnSave)),(e=e&&!!ke.period.id)&&!ke.isMode("view")}function I(){ke.isSelfRecord?ke.request.status_id=ke.requestStatuses[_.statusNames.awaitingApproval].value:ke.canManage&&(ke.request.status_id=ke.newStatusOnSave||ke.request.status_id)}function x(){if(ke.isMode("edit")&&!ke.isRole("staff")&&"toil"!==F())return ke.request.calculateBalanceChange(ke.selectedAbsenceType.calculation_unit_name).then(function(e){if(+ke.balance.change.amount!=+e.amount)return w.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function O(){ke.errors=[]}function L(){return ke.request.create().then($e).then(function(){me("LeaveRequest::new")})}function k(){ee()&&!ke.isRole("staff")&&(ke.request.change_balance=!0)}function M(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return ke.request.delete().then(function(){ke.dismissModal(),d.publish("LeaveRequest::delete",ke.request)})}})}function E(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(ke.getStatusFromValue(ke.request.status_id).name)}function N(e){return n.map(De[e],function(e){return ke.requestStatuses[e]})}function F(){return ke.request?ke.request.request_type:ke.leaveType||null}function U(){return!ke.request||e.equals({},ke.requestStatuses)?[]:ke.request.status_id?B():N("none")}function H(e){return n.find(ke.requestStatuses,function(t){return t.value===e})}function V(e){ke.errors=n.isArray(e)?e:[e],ke.loading.absenceTypes=!1,ke.submitting=!1}function W(){return!e.equals(Se,ke.request.attributes())||ke.canManage&&ke.newStatusOnSave}function G(){return ke.postContactSelection=!0,ke.staffMemberSelectionComplete=!1,ke.request.contact_id?r.resolve().then(ie).then(ue).then(he).then(ge).then(Z).then(z).then(ke.isMode("edit")?be:n.noop).then(function(){ke.postContactSelection=!1,ke.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==xe)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];De.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],De.awaiting_approval=e,De.more_information_required=e,De.rejected=e,De.approved=e,De.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return ke.canManage?m.find(ke.request.contact_id).then(function(e){ke.contactName=e.display_name}):r.resolve()}function J(){Te.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(he).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",ke.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){V(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){Re++})),s.$on("$destroy",we),s.$on("LeaveRequestPopup::addTab",function(e,t){Le.push(t)})}function K(){var e,t;ke.request=ke.leaveRequest||null,e=F(),t=ke.initRequestAttributes(),"leave"===e?ke.request=y.init(t):"sickness"===e?ke.request=q.init(t):"toil"===e&&(ke.request=$.init(t))}function X(){var e={};return ke.request?e=ke.request.attributes():ke.canManage||(e={contact_id:Ie}),e}function Q(){if(Oe="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(Oe="admin")}).then(function(){return"staff"===Oe&&u(_.permissions.ssp.manage).then(function(e){e&&(Oe="manager")})}).finally(function(){ke.canManage=ke.isRole("manager")||ke.isRole("admin")})}function Z(){(ke.isRole("admin")||ke.isMode("create")&&ke.isRole("manager"))&&(ke.newStatusOnSave=ke.requestStatuses[_.statusNames.approved].value)}function ee(){return!ke.request.status_id||!n.includes(["cancelled","rejected"],H(ke.request.status_id).name)}function te(e){var t=ke.getStatusFromValue(ke.request.status_id);return!!t&&t.name===e}function ne(e){return ke.request&&ke.request.request_type===e}function ae(e){return ke.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date)&&r.isSameOrBefore(t.end_date)}function oe(e){return Oe===e}function se(){return h.all().then(function(e){ke.absencePeriods=e})}function ie(){return v.all(j()).then(v.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return ke.loading.entitlements=!0,g.all({contact_id:ke.request.contact_id,period_id:ke.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){ke.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Ie=e.contactId})}function le(){return ke.selectedContactId?m.find(ke.selectedContactId).then(function(e){ke.managedContacts=[e]}):ke.isRole("admin")?m.all().then(function(e){ke.managedContacts=n.remove(e.list,function(e){return e.id!==Ie})}):m.find(Ie).then(function(e){return e.leaveManagees()}).then(function(e){ke.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){ke.requestStatuses=n.indexBy(e,"name")})}function fe(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function me(e){P(),d.publish(e,ke.request),ke.errors=[],ke.dismissModal()}function pe(){["from","to"].forEach(function(e){ke.request[e+"_date"]=Se[e+"_date"]})}function he(e){if(ke.absenceTypes=fe(Pe.types,e),!ke.absenceTypes.length)return r.reject(xe)}function ve(){ke.period=n.find(ke.absencePeriods,function(e){return ke.isMode("create")?e.current:re(ke.request,e)})}function ge(){ke.isMode("create")?(ke.selectedAbsenceType=ke.absenceTypes[0],ke.request.type_id=ke.selectedAbsenceType.id):ke.selectedAbsenceType=n.find(ke.absenceTypes,function(e){return e.id===ke.request.type_id})}function be(){Se=e.copy(ke.request.attributes())}function ye(){var e;ke.request.id?(e=[ke.requestStatuses[_.statusNames.approved].value,ke.requestStatuses[_.statusNames.adminApproved].value,ke.requestStatuses[_.statusNames.rejected].value,ke.requestStatuses[_.statusNames.cancelled].value],ke.mode="edit",ke.isRole("staff")&&e.indexOf(ke.request.status_id)>-1&&(ke.mode="view")):ke.mode="create"}function _e(){var e=ke.request.status_id;if(!ke.isMode("view")&&!ke.submitting)return ke.submitting=!0,I(),A(),ke.request.isValid().then(ee()&&x).then(k).then(!ke.request.change_balance&&pe).then(qe).then(function(){return ke.isMode("edit")?Ae():L()}).catch(function(t){ke.request.status_id=e,t&&V(t)}).finally(function(){ke.submitting=!1})}function qe(){return r.all(Le.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===Re&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return Re>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function we(){Te.forEach(function(e){e()})}function Ce(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function Ae(){return ke.request.update().then($e).then(function(){ke.isRole("manager")?me("LeaveRequest::updatedByManager"):(ke.isRole("staff")||ke.isRole("admin"))&&me("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,De={},Re=0,Se={},Te=[],Ie="",xe="No entitlement",Oe="",Le=[],ke=n.assign(this,f);ke.absencePeriods=[],ke.absenceTypes=[],ke.canManage=!1,ke.contactName=null,ke.errors=[],ke.loading={absenceTypes:!0,entitlements:!0},ke.managedContacts=[],ke.mode="",ke.newStatusOnSave=null,ke.period={},ke.postContactSelection=!1,ke.requestStatuses={},ke.selectedAbsenceType={},ke.staffMemberSelectionComplete=!1,ke.submitting=!1,ke.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},ke.canChangeAbsenceType=S,ke.canSubmit=T,ke.closeAlert=O,ke.deleteLeaveRequest=M,ke.dismissModal=E,ke.getStatuses=U,ke.getStatusFromValue=H,ke.initAfterContactSelection=G,ke.initRequestAttributes=X,ke.isLeaveStatus=te,ke.isLeaveType=ne,ke.isMode=ae,ke.isRole=oe,ke.submit=_e,ke.updateAbsenceType=Ce,function(){ke.loading.absenceTypes=!0,Y(),J(),r.all([ce(),Q(),se(),de()]).then(K).then(ye).then(ve).then(function(){return ke.canManage&&!ke.isMode("edit")&&le()}).then(function(){if(ke.selectedContactId&&(ke.request.contact_id=ke.selectedContactId),ke.request.contact_id)return ke.initAfterContactSelection()}).catch(V).finally(function(){ke.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/my-leave/modules/components",["common/angular"],function(e){return e.module("my-leave.components",[])}),define("leave-absences/my-leave/components/my-leave-container.component",["leave-absences/my-leave/modules/components"],function(e){e.component("myLeaveContainer",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/my-leave-container.html"}],controllerAs:"myleave",controller:["$log","$rootScope","$state",function(e,t,n){function a(){n.go(r.tabName)}e.debug("Component: my-leave-container"),t.section="my-leave";var r=this;r.tabName=n.current.name,r.changeTab=a}]})}),function(e){define("leave-absences/my-leave/modules/settings",["common/angular"],function(t){return t.module("my-leave.settings",[]).constant("settings",{debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/my-leave/"})})}(CRM),function(e){define("leave-absences/my-leave/modules/config",["common/angular","leave-absences/my-leave/modules/settings"],function(t){return t.module("my-leave.config",["my-leave.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(t,n,a,r,o,s){o.debugEnabled(s.debug),n.defaults.stripTrailingSlashes=!1,r.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",a.otherwise("/my-leave/report"),t.state("my-leave",{abstract:!0,url:"/my-leave",template:'',resolve:{contactId:function(){return e.vars.leaveAndAbsences.contactId},format:["DateFormat",function(e){return e.getDateFormat()}]}}).state("my-leave.report",{url:"/report?leave-request-id",template:'',onEnter:["$stateParams","LeavePopup",function(e,t){e["leave-request-id"]&&t.openModalByID(e["leave-request-id"])}]}).state("my-leave.calendar",{url:"/calendar",template:''})}])})}(CRM),define("leave-absences/my-leave/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/loading","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/models/option-group","common/modules/dialog","common/services/check-permissions","common/services/angular-date/date-format","leave-absences/shared/ui-router","leave-absences/shared/modules/shared-settings","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/staff-leave-report.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/my-leave/components/my-leave-container.component","leave-absences/my-leave/modules/config"],function(e){return e.module("my-leave",["ngResource","ngAnimate","ui.bootstrap","ui.router","textAngular","common.angularDate","common.dialog","common.directives","common.filters","common.mocks","common.models","common.services","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","leave-absences.settings","my-leave.components","my-leave.config"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/my-leave":n+"/my-leave"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/my-leave/app"],function(e){e.bootstrap(document.querySelector("[data-leave-absences-my-leave]"),["my-leave"])})})}(CRM,require),define("my-leave",function(){}); +!function(e){define("leave-absences/shared/config",[],function(){var t=CRM.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences/shared";e.config({paths:{"leave-absences/shared/ui-router":"leave-absences/shared/vendor/angular-ui-router.min",mocks:"../test/mocks"},shim:{"leave-absences/shared/ui-router":{}}}),e.config({paths:{"leave-absences/shared/ui-router":t+"/vendor/angular-ui-router.min",mocks:CRM.vars.leaveAndAbsences.baseURL+"/js/angular/test/mocks"}})})}(require),function(e){define("leave-absences/shared/ui-router",[],function(){return function(){"undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(e,t,n){"use strict";function a(e,t){return W(new(W(function(){},{prototype:e})),t)}function r(e){return H(arguments,function(t){t!==e&&H(t,function(t,n){e.hasOwnProperty(n)||(e[n]=t)})}),e}function o(e,t){var n=[];for(var a in e.path){if(e.path[a]!==t.path[a])break;n.push(e.path[a])}return n}function s(e){if(Object.keys)return Object.keys(e);var t=[];return H(e,function(e,n){t.push(n)}),t}function i(e,t){if(Array.prototype.indexOf)return e.indexOf(t,Number(arguments[2])||0);var n=e.length>>>0,a=Number(arguments[2])||0;for((a=a<0?Math.ceil(a):Math.floor(a))<0&&(a+=n);a=0||(l.push(r[m]),c[r[m]]=e[r[m]]);return W({},c,t)}function c(e,t,n){if(!n){n=[];for(var a in e)n.push(a)}for(var r=0;r "));if(b[n]=a,N(e))v.push(n,[function(){return t.get(e)}],c);else{var r=t.annotate(e);H(r,function(e){e!==n&&u.hasOwnProperty(e)&&f(u[e],e)}),v.push(n,e,r)}g.pop(),b[n]=o}}function p(e){return F(e)&&e.then&&e.$$promises}if(!F(u))throw new Error("'invocables' must be an object");var h=s(u||{}),v=[],g=[],b={};return H(u,f),u=g=b=null,function(a,o,s){function i(){--y||(_||r(b,o.$$values),f.$$values=b,f.$$promises=f.$$promises||!0,delete f.$$inheritedValues,c.resolve(b))}function u(e){f.$$failure=e,c.reject(e)}if(p(a)&&s===n&&(s=o,o=a,a=null),a){if(!F(a))throw new Error("'locals' must be an object")}else a=l;if(o){if(!p(o))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else o=d;var c=e.defer(),f=c.promise,g=f.$$promises={},b=W({},a),y=1+v.length/3,_=!1;if(j(o.$$failure))return u(o.$$failure),f;o.$$inheritedValues&&r(b,m(o.$$inheritedValues,h)),W(g,o.$$promises),o.$$values?(_=r(b,m(o.$$values,h)),f.$$inheritedValues=m(o.$$values,h),i()):(o.$$inheritedValues&&(f.$$inheritedValues=m(o.$$inheritedValues,h)),o.then(i,u));for(var q=0,$=v.length;q<$;q+=3)a.hasOwnProperty(v[q])?i():function(n,r,o){function c(e){d.reject(e),u(e)}function l(){if(!j(f.$$failure))try{d.resolve(t.invoke(r,s,b)),d.promise.then(function(e){b[n]=e,i()},c)}catch(e){c(e)}}var d=e.defer(),m=0;H(o,function(e){g.hasOwnProperty(e)&&!a.hasOwnProperty(e)&&(m++,g[e].then(function(t){b[e]=t,--m||l()},c))}),m||l(),g[n]=d.promise}(v[q],v[q+1],v[q+2]);return f}},this.resolve=function(e,t,n,a){return this.study(e)(t,n,a)}}function g(e,t,n){this.fromConfig=function(e,t,n){return j(e.template)?this.fromString(e.template,t):j(e.templateUrl)?this.fromUrl(e.templateUrl,t):j(e.templateProvider)?this.fromProvider(e.templateProvider,t,n):null},this.fromString=function(e,t){return B(e)?e(t):e},this.fromUrl=function(n,a){return B(n)&&(n=n(a)),null==n?null:e.get(n,{cache:t,headers:{Accept:"text/html"}}).then(function(e){return e.data})},this.fromProvider=function(e,t,a){return n.invoke(e,null,a||{params:t})}}function b(e,t,r){function o(t,n,a,r){if(v.push(t),p[t])return p[t];if(!/^\w+([-.]+\w+)*(?:\[\])?$/.test(t))throw new Error("Invalid parameter name '"+t+"' in pattern '"+e+"'");if(h[t])throw new Error("Duplicate parameter name '"+t+"' in pattern '"+e+"'");return h[t]=new Y.Param(t,n,a,r),h[t]}function s(e,t,n,a){var r=["",""],o=e.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!t)return o;switch(n){case!1:r=["(",")"+(a?"?":"")];break;case!0:o=o.replace(/\/$/,""),r=["(?:/(",")|/)?"];break;default:r=["("+n+"|",")?"]}return o+r[0]+t+r[1]}function i(r,o){var s,i,u,c,l;return s=r[2]||r[3],l=t.params[s],u=e.substring(m,r.index),i=o?r[4]:r[4]||("*"==r[1]?".*":null),i&&(c=Y.type(i)||a(Y.type("string"),{pattern:new RegExp(i,t.caseInsensitive?"i":n)})),{id:s,regexp:i,segment:u,type:c,cfg:l}}t=W({params:{}},F(t)?t:{});var u,c=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l=/([:]?)([\w\[\].-]+)|\{([\w\[\].-]+)(?:\:\s*((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,d="^",m=0,f=this.segments=[],p=r?r.params:{},h=this.params=r?r.params.$$new():new Y.ParamSet,v=[];this.source=e;for(var g,b,y;(u=c.exec(e))&&(g=i(u,!1),!(g.segment.indexOf("?")>=0));)b=o(g.id,g.type,g.cfg,"path"),d+=s(g.segment,b.type.pattern.source,b.squash,b.isOptional),f.push(g.segment),m=c.lastIndex;y=e.substring(m);var _=y.indexOf("?");if(_>=0){var q=this.sourceSearch=y.substring(_);if(y=y.substring(0,_),this.sourcePath=e.substring(0,m+_),q.length>0)for(m=0;u=l.exec(q);)g=i(u,!0),b=o(g.id,g.type,g.cfg,"search"),m=c.lastIndex}else this.sourcePath=e,this.sourceSearch="";d+=s(y)+(!1===t.strict?"/?":"")+"$",f.push(y),this.regexp=new RegExp(d,t.caseInsensitive?"i":n),this.prefix=f[0],this.$$paramNames=v}function y(e){W(this,e)}function _(){function e(e){return null!=e?e.toString().replace(/(~|\/)/g,function(e){return{"~":"~~","/":"~2F"}[e]}):e}function r(e){return null!=e?e.toString().replace(/(~~|~2F)/g,function(e){return{"~~":"~","~2F":"/"}[e]}):e}function o(){return{strict:h,caseInsensitive:m}}function u(e){return B(e)||U(e)&&B(e[e.length-1])}function c(){for(;$.length;){var e=$.shift();if(e.pattern)throw new Error("You cannot override a type's .pattern at runtime.");t.extend(g[e.name],d.invoke(e.def))}}function l(e){W(this,e||{})}Y=this;var d,m=!1,h=!0,v=!1,g={},q=!0,$=[],w={string:{encode:e,decode:r,is:function(e){return null==e||!j(e)||"string"==typeof e},pattern:/[^\/]*/},int:{encode:e,decode:function(e){return parseInt(e,10)},is:function(e){return j(e)&&this.decode(e.toString())===e},pattern:/\d+/},bool:{encode:function(e){return e?1:0},decode:function(e){return 0!==parseInt(e,10)},is:function(e){return!0===e||!1===e},pattern:/0|1/},date:{encode:function(e){return this.is(e)?[e.getFullYear(),("0"+(e.getMonth()+1)).slice(-2),("0"+e.getDate()).slice(-2)].join("-"):n},decode:function(e){if(this.is(e))return e;var t=this.capture.exec(e);return t?new Date(t[1],t[2]-1,t[3]):n},is:function(e){return e instanceof Date&&!isNaN(e.valueOf())},equals:function(e,t){return this.is(e)&&this.is(t)&&e.toISOString()===t.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:t.toJson,decode:t.fromJson,is:t.isObject,equals:t.equals,pattern:/[^\/]*/},any:{encode:t.identity,decode:t.identity,equals:t.equals,pattern:/.*/}};_.$$getDefaultValue=function(e){if(!u(e.value))return e.value;if(!d)throw new Error("Injectable functions cannot be called at configuration time");return d.invoke(e.value)},this.caseInsensitive=function(e){return j(e)&&(m=e),m},this.strictMode=function(e){return j(e)&&(h=e),h},this.defaultSquashPolicy=function(e){if(!j(e))return v;if(!0!==e&&!1!==e&&!N(e))throw new Error("Invalid squash policy: "+e+". Valid policies: false, true, arbitrary-string");return v=e,e},this.compile=function(e,t){return new b(e,W(o(),t))},this.isMatcher=function(e){if(!F(e))return!1;var t=!0;return H(b.prototype,function(n,a){B(n)&&(t=t&&j(e[a])&&B(e[a]))}),t},this.type=function(e,t,n){if(!j(t))return g[e];if(g.hasOwnProperty(e))throw new Error("A type named '"+e+"' has already been defined.");return g[e]=new y(W({name:e},t)),n&&($.push({name:e,def:n}),q||c()),this},H(w,function(e,t){g[t]=new y(W({name:t},e))}),g=a(g,{}),this.$get=["$injector",function(e){return d=e,q=!1,c(),H(w,function(e,t){g[t]||(g[t]=new y(e))}),this}],this.Param=function(e,a,r,o){function c(){if(!d)throw new Error("Injectable functions cannot be called at configuration time");var e=d.invoke(r.$$fn);if(null!==e&&e!==n&&!h.type.is(e))throw new Error("Default value ("+e+") for parameter '"+h.id+"' is not an instance of Type ("+h.type.name+")");return e}function l(e){function t(e){return function(t){return t.from===e}}return e=function(e){var n=p(f(h.replace,t(e)),function(e){return e.to});return n.length?n[0]:e}(e),j(e)?h.type.$normalize(e):c()}function m(){return"{Param:"+e+" "+a+" squash: '"+q+"' optional: "+_+"}"}var h=this;r=function(e){var t=F(e)?s(e):[];return-1===i(t,"value")&&-1===i(t,"type")&&-1===i(t,"squash")&&-1===i(t,"array")&&(e={value:e}),e.$$fn=u(e.value)?e.value:function(){return e.value},e}(r),a=function(n,a,r){if(n.type&&a)throw new Error("Param '"+e+"' has two type configurations.");return a||(n.type?t.isString(n.type)?g[n.type]:n.type instanceof y?n.type:new y(n.type):"config"===r?g.any:g.string)}(r,a,o);var b=function(){var t={array:"search"===o&&"auto"},n=e.match(/\[\]$/)?{array:!0}:{};return W(t,n,r).array}();a=b?a.$asArray(b,"search"===o):a,"string"!==a.name||b||"path"!==o||r.value!==n||(r.value="");var _=r.value!==n,q=function(e,t){var n=e.squash;if(!t||!1===n)return!1;if(!j(n)||null==n)return v;if(!0===n||N(n))return n;throw new Error("Invalid squash policy: '"+n+"'. Valid policies: false, true, or arbitrary string")}(r,_),$=function(e,t,a,r){var o,s,u=[{from:"",to:a||t?n:""},{from:null,to:a||t?n:""}];return o=U(e.replace)?e.replace:[],N(r)&&o.push({from:r,to:n}),s=p(o,function(e){return e.from}),f(u,function(e){return-1===i(s,e.from)}).concat(o)}(r,b,_,q);W(this,{id:e,type:a,location:o,array:b,squash:q,replace:$,isOptional:_,value:l,dynamic:n,config:r,toString:m})},l.prototype={$$new:function(){return a(this,W(new l,{$$parent:this}))},$$keys:function(){for(var e=[],t=[],n=this,a=s(l.prototype);n;)t.push(n),n=n.$$parent;return t.reverse(),H(t,function(t){H(s(t),function(t){-1===i(e,t)&&-1===i(a,t)&&e.push(t)})}),e},$$values:function(e){var t={},n=this;return H(n.$$keys(),function(a){t[a]=n[a].value(e&&e[a])}),t},$$equals:function(e,t){var n=!0,a=this;return H(a.$$keys(),function(r){var o=e&&e[r],s=t&&t[r];a[r].type.equals(o,s)||(n=!1)}),n},$$validates:function(e){var a,r,o,s,i,u=this.$$keys();for(a=0;a=0)throw new Error("State must have a valid name");if(P.hasOwnProperty(n))throw new Error("State '"+n+"' is already defined");var r=-1!==n.indexOf(".")?n.substring(0,n.lastIndexOf(".")):N(t.parent)?t.parent:F(t.parent)&&N(t.parent.name)?t.parent.name:"";if(r&&!P[r])return f(r,t.self);for(var o in S)B(S[o])&&(t[o]=S[o](t,S.$delegates[o]));return P[n]=t,!t[T]&&t.url&&e.when(t.url,["$match","$stateParams",function(e,n){A.$current.navigable==t&&c(e,n)||A.transitionTo(t,e,{inherit:!0,location:!1})}]),v(n),t}function b(e){return e.indexOf("*")>-1}function y(e){for(var t=e.split("."),n=A.$current.name.split("."),a=0,r=t.length;a=P;a--)s=p[a],s.self.onExit&&i.invoke(s.self.onExit,s.self,s.locals.globals),s.locals=null;for(a=P;a<_.length;a++)r=_[a],r.locals=E[a],r.self.onEnter&&i.invoke(r.self.onEnter,r.self,r.locals.globals);return A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.$current=t,A.current=t.self,A.params=n,V(A.params,f),A.transition=null,o.location&&t.navigable&&v.push(t.navigable.url,t.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===o.location}),o.notify&&e.$broadcast("$stateChangeSuccess",t.self,n,c.self,d),v.update(!0),A.current)}).then(null,function(a){return a===D?S:A.transition!==B?(e.$broadcast("$stateChangeCancel",t.self,n,c.self,d),S):(A.transition=null,s=e.$broadcast("$stateChangeError",t.self,n,c.self,d,a),s.defaultPrevented||v.update(),r.reject(a))});return B},A.is=function(e,t,a){a=W({relative:A.$current},a||{});var r=m(e,a.relative);return j(r)?A.$current===r&&(!t||c(r.params.$$values(t),f)):n},A.includes=function(e,t,a){if(a=W({relative:A.$current},a||{}),N(e)&&b(e)){if(!y(e))return!1;e=A.$current.name}var r=m(e,a.relative);if(!j(r))return n;if(!j(A.$current.includes[r.name]))return!1;if(!t)return!0;for(var o=s(t),i=0;i2?c.enter(e,null,n).then(a):c.enter(e,null,n,a)},leave:function(e,n){t.version.minor>2?c.leave(e).then(n):c.leave(e,n)}};if(u){var a=u&&u(n,e);return{enter:function(e,t,n){a.enter(e,null,t),n()},leave:function(e,t){a.leave(e),t()}}}return function(){return{enter:function(e,t,n){t.after(e),n()},leave:function(e,t){e.remove(),t()}}}()}var i=function(){return n.has?function(e){return n.has(e)?n.get(e):null}:function(e){try{return n.get(e)}catch(e){return null}}}(),u=i("$animator"),c=i("$animate");return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(n,i,u){return function(n,i,c){function l(){if(m&&(m.remove(),m=null),p&&(p.$destroy(),p=null),f){var e=f.data("$uiViewAnim");b.leave(f,function(){e.$$animLeave.resolve(),m=null}),m=f,f=null}}function d(s){var d,m=D(n,c,i,r),y=m&&e.$current&&e.$current.locals[m];if(s||y!==h){d=n.$new(),h=e.$current.locals[m],d.$emit("$viewContentLoading",m);var _=u(d,function(e){var r=o.defer(),s=o.defer(),u={$animEnter:r.promise,$animLeave:s.promise,$$animLeave:s};e.data("$uiViewAnim",u),b.enter(e,i,function(){r.resolve(),p&&p.$emit("$viewContentAnimationEnded"),(t.isDefined(g)&&!g||n.$eval(g))&&a(e)}),l()});f=_,p=d,p.$emit("$viewContentLoaded",m),p.$eval(v)}}var m,f,p,h,v=c.onload||"",g=c.autoscroll,b=s(c,n);i.inheritedData("$uiView"),n.$on("$stateChangeSuccess",function(){d(!1)}),d(!0)}}}}function P(e,n,a,r){return{restrict:"ECA",priority:-400,compile:function(o){var s=o.html();return function(o,i,u){var c=a.$current,l=D(o,u,i,r),d=c&&c.locals[l];if(d){i.data("$uiView",{name:l,state:d.$$state}),i.html(d.$template?d.$template:s);var m=t.extend({},d);o[d.$$resolveAs]=m;var f=e(i.contents());if(d.$$controller){d.$scope=o,d.$element=i;var p=n(d.$$controller,d);d.$$controllerAs&&(o[d.$$controllerAs]=p,o[d.$$controllerAs][d.$$resolveAs]=m),B(p.$onInit)&&p.$onInit(),i.data("$ngControllerController",p),i.children().data("$ngControllerController",p)}f(o)}}}}}function D(e,t,n,a){var r=a(t.uiView||t.name||"")(e),o=n.inheritedData("$uiView");return r.indexOf("@")>=0?r:r+"@"+(o?o.state.name:"")}function T(e,t){var n,a=e.match(/^\s*({[^}]*})\s*$/);if(a&&(e=t+"("+a[1]+")"),!(n=e.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/))||4!==n.length)throw new Error("Invalid state ref '"+e+"'");return{state:n[1],paramExpr:n[3]||null}}function S(e){var t=e.parent().inheritedData("$uiView");if(t&&t.state&&t.state.name)return t.state}function R(e){var t="[object SVGAnimatedString]"===Object.prototype.toString.call(e.prop("href")),n="FORM"===e[0].nodeName;return{attr:n?"action":t?"xlink:href":"href",isAnchor:"A"===e.prop("tagName").toUpperCase(),clickable:!n}}function O(e,t,n,a,r){return function(o){var s=o.which||o.button,i=r();if(!(s>1||o.ctrlKey||o.metaKey||o.shiftKey||e.attr("target"))){var u=n(function(){t.go(i.state,i.params,i.options)});o.preventDefault();var c=a.isAnchor&&!i.href?1:0;o.preventDefault=function(){c--<=0&&n.cancel(u)}}}}function I(e,t){return{relative:S(e)||t.$current,inherit:!0}}function x(e,n){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(a,r,o,s){var i,u=T(o.uiSref,e.current.name),c={state:u.state,href:null,params:null},l=R(r),d=s[1]||s[0],m=null;c.options=W(I(r,e),o.uiSrefOpts?a.$eval(o.uiSrefOpts):{});var f=function(n){n&&(c.params=t.copy(n)),c.href=e.href(u.state,c.params,c.options),m&&m(),d&&(m=d.$$addStateInfo(u.state,c.params)),null!==c.href&&o.$set(l.attr,c.href)};u.paramExpr&&(a.$watch(u.paramExpr,function(e){e!==c.params&&f(e)},!0),c.params=t.copy(a.$eval(u.paramExpr))),f(),l.clickable&&(i=O(r,e,n,l,function(){return c}),r[r.on?"on":"bind"]("click",i),a.$on("$destroy",function(){r[r.off?"off":"unbind"]("click",i)}))}}}function E(e,t){return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(n,a,r,o){function s(t){m.state=t[0],m.params=t[1],m.options=t[2],m.href=e.href(m.state,m.params,m.options),f&&f(),c&&(f=c.$$addStateInfo(m.state,m.params)),m.href&&r.$set(u.attr,m.href)}var i,u=R(a),c=o[1]||o[0],l=[r.uiState,r.uiStateParams||null,r.uiStateOpts||null],d="["+l.map(function(e){return e||"null"}).join(", ")+"]",m={state:null,params:null,options:null,href:null},f=null;n.$watch(d,s,!0),s(n.$eval(d)),u.clickable&&(i=O(a,e,t,u,function(){return m}),a[a.on?"on":"bind"]("click",i),n.$on("$destroy",function(){a[a.off?"off":"unbind"]("click",i)}))}}}function L(e,t,n){return{restrict:"A",controller:["$scope","$element","$attrs","$timeout",function(t,a,r,o){function s(t,n,r){var o=e.get(t,S(a)),s=i(t,n),u={state:o||{name:t},params:n,hash:s};return h.push(u),v[s]=r,function(){var e=h.indexOf(u);-1!==e&&h.splice(e,1)}}function i(e,n){if(!N(e))throw new Error("state should be a string");return F(n)?e+G(n):(n=t.$eval(n),F(n)?e+G(n):e)}function u(){for(var e=0;e0)){var n=s(e,t,p);return u(),n}},t.$on("$stateChangeSuccess",u),u()}]}}function M(e){var t=function(t,n){return e.is(t,n)};return t.$stateful=!0,t}function k(e){var t=function(t,n,a){return e.includes(t,n,a)};return t.$stateful=!0,t}var j=t.isDefined,B=t.isFunction,N=t.isString,F=t.isObject,U=t.isArray,H=t.forEach,W=t.extend,V=t.copy,G=t.toJson;t.module("ui.router.util",["ng"]),t.module("ui.router.router",["ui.router.util"]),t.module("ui.router.state",["ui.router.router","ui.router.util"]),t.module("ui.router",["ui.router.state"]),t.module("ui.router.compat",["ui.router"]),v.$inject=["$q","$injector"],t.module("ui.router.util").service("$resolve",v),g.$inject=["$http","$templateCache","$injector"],t.module("ui.router.util").service("$templateFactory",g);var Y;b.prototype.concat=function(e,t){var n={caseInsensitive:Y.caseInsensitive(),strict:Y.strictMode(),squash:Y.defaultSquashPolicy()};return new b(this.sourcePath+e+this.sourceSearch,W(n,t),this)},b.prototype.toString=function(){return this.source},b.prototype.exec=function(e,t){var n=this.regexp.exec(e);if(!n)return null;t=t||{};var a,r,o,s=this.parameters(),i=s.length,u=this.segments.length-1,c={};if(u!==n.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");var l,d;for(a=0;a=":e}};return a.all(n).then(function(e){return e&&e.length?r.init(e[0],!0):null})}})}])}),define("leave-absences/shared/apis/absence-type.api",["common/lodash","common/moment","leave-absences/shared/modules/apis","common/services/api"],function(e,t,n){"use strict";n.factory("AbsenceTypeAPI",["$log","api","shared-settings",function(n,a,r){return n.debug("AbsenceTypeAPI"),a.extend({all:function(t){return n.debug("AbsenceTypeAPI.all"),this.sendGET("AbsenceType","get",e.defaultsDeep(t||{},{is_active:!0,options:{sort:"weight ASC"}})).then(function(e){return e.values})},calculateToilExpiryDate:function(a,o,s){return n.debug("AbsenceTypeAPI.calculateToilExpiryDate"),s=e.assign({},s,{absence_type_id:a,date:t(o).format(r.serverDateFormat)}),this.sendPOST("AbsenceType","calculateToilExpiryDate",s).then(function(e){return e.values.expiry_date})}})}])}),define("leave-absences/shared/instances/absence-type.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("AbsenceTypeInstance",["$log","ModelInstance",function(e,t){return e.debug("AbsenceTypeInstance"),t.extend({})}])}),define("leave-absences/shared/models/absence-type.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","common/models/option-group","leave-absences/shared/apis/absence-type.api","leave-absences/shared/instances/absence-type.instance"],function(e,t){"use strict";t.factory("AbsenceType",["$log","$q","Model","OptionGroup","AbsenceTypeAPI","AbsenceTypeInstance",function(t,n,a,r,o,s){return t.debug("AbsenceType"),a.extend({all:function(e){return o.all(e).then(function(e){return e.map(function(e){return s.init(e,!0)})})},calculateToilExpiryDate:function(e,t,n){return o.calculateToilExpiryDate(e,t,n)},canExpire:function(e){return o.all({accrual_expiration_unit:{"IS NOT NULL":1},accrual_expiration_duration:{"IS NOT NULL":1},allow_accruals_request:1,id:e,options:{limit:1},return:["id"]}).then(function(e){return e.length>0})},loadCalculationUnits:function(t){return r.valuesOf("hrleaveandabsences_absence_type_calculation_unit").then(function(n){return n=e.indexBy(n,"value"),e.map(t,function(t){return e.assign(t,{calculation_unit_label:n[t.calculation_unit].label,calculation_unit_name:n[t.calculation_unit].name})})})}})}])}),define("leave-absences/shared/apis/work-pattern.api",["common/lodash","leave-absences/shared/modules/apis","common/services/api"],function(e,t){"use strict";t.factory("WorkPatternAPI",["$log","api",function(t,n){function a(t){var n=e.clone(t);return n.workPattern=n["api.WorkPattern.get"].values[0],delete n["api.WorkPattern.get"],n}return t.debug("WorkPatternAPI"),n.extend({assignWorkPattern:function(t,n,a,r,o,s){return this.sendPOST("ContactWorkPattern","create",e.assign({},s,{contact_id:t,pattern_id:n,effective_date:a,effective_end_date:r,change_reason:o})).then(function(e){return e.values})},get:function(e){return this.sendGET("WorkPattern","get",e||{}).then(function(e){return e.values})},getCalendar:function(n,a,r,o){return t.debug("WorkPatternAPI.getCalendar",n,a,r,o),this.sendGET("WorkPattern","getcalendar",e.assign({},o,{contact_id:e.isArray(n)?{IN:n}:n,start_date:a,end_date:r}))},unassignWorkPattern:function(e){return this.sendPOST("ContactWorkPattern","delete",{id:e})},workPatternsOf:function(t,n,r){return this.sendGET("ContactWorkPattern","get",e.assign({},n,{contact_id:t,"api.WorkPattern.get":{id:"$value.pattern_id"}}),r).then(function(e){return e=e.values,e.map(a)})}})}])}),define("leave-absences/shared/instances/calendar.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance"],function(e,t,n){"use strict";n.factory("CalendarInstance",["$log","$q","ModelInstance","shared-settings","OptionGroup",function(n,a,r,o,s){function i(t,n){return c().then(function(a){var r=this.days[u(t).valueOf()];return!!r&&e.find(a,function(e){return e.name===n}).value===r.type}.bind(this))}function u(e){return t(e,o.serverDateFormat).clone()}function c(){return l=l||s.valuesOf("hrleaveandabsences_work_day_type")}var l;return r.extend({defaultCustomData:function(){return{days:[]}},isNonWorkingDay:function(e){return i.call(this,e,"non_working_day")},isWeekend:function(e){return i.call(this,e,"weekend")},isWorkingDay:function(e){return i.call(this,e,"working_day")},transformAttributes:function(t){var n={};return t.calendar.forEach(function(e){n[u(e.date).valueOf()]=e}),e(t).omit("calendar").assign({days:n}).value()}})}])}),define("leave-absences/shared/models/calendar.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/work-pattern.api","leave-absences/shared/instances/calendar.instance"],function(e,t){"use strict";t.factory("Calendar",["$log","Model","WorkPatternAPI","CalendarInstance",function(t,n,a,r){return t.debug("Calendar"),n.extend({get:function(n,o,s,i){return t.debug("Calendar.get"),a.getCalendar(n,o,s,i).then(function(t){var a=t.values.map(function(e){return r.init(e)});return e.isArray(n)?a:a[0]})}})}])}),define("leave-absences/shared/apis/entitlement.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("EntitlementAPI",["$log","api",function(e,n){function a(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getremainder"].values;return a.length&&(n.remainder=a[0].remainder),delete n["api.LeavePeriodEntitlement.getremainder"],n}function r(e){var n=t.clone(e),a=n["api.LeavePeriodEntitlement.getentitlement"].values[0].entitlement;return n.value=a,delete n["api.LeavePeriodEntitlement.getentitlement"],n}return e.debug("EntitlementAPI"),n.extend({all:function(t,n){return e.debug("EntitlementAPI.all"),t["api.LeavePeriodEntitlement.getentitlement"]={entitlement_id:"$value.id"},n&&(t["api.LeavePeriodEntitlement.getremainder"]={entitlement_id:"$value.id",include_future:!0}),this.sendGET("LeavePeriodEntitlement","get",t,!1).then(function(e){return e.values}).then(function(e){return e=e.map(r),n&&(e=e.map(a)),e})},breakdown:function(t){return e.debug("EntitlementAPI.breakdown"),this.sendGET("LeavePeriodEntitlement","getbreakdown",t).then(function(e){return e.values})},getLeaveBalances:function(t,n,a,r,o){return e.debug("EntitlementAPI.getLeaveBalances"),this.getAll("LeavePeriodEntitlement",t,n,a,r,"getLeaveBalances",o)}})}])}),define("leave-absences/shared/apis/entitlement-log.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("EntitlementLogAPI",["$log","api",function(e,t){return e.debug("EntitlementLogAPI"),t.extend({all:function(t){return e.debug("EntitlementLogAPI.all"),this.sendGET("LeavePeriodEntitlementLog","get",t,!1).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/entitlement.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("EntitlementInstance",["$log","ModelInstance","EntitlementAPI",function(e,t,n){return e.debug("EntitlementInstance"),t.extend({defaultCustomData:function(){return{remainder:{current:0,future:0},breakdown:[]}},getBreakdown:function(){return n.breakdown({entitlement_id:this.id}).then(function(e){this.breakdown=e}.bind(this))}})}])}),define("leave-absences/shared/models/entitlement.model",["common/lodash","leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/entitlement.api","leave-absences/shared/apis/entitlement-log.api","leave-absences/shared/instances/entitlement.instance"],function(e,t){"use strict";t.factory("Entitlement",["$log","Model","EntitlementAPI","EntitlementInstance","EntitlementLogAPI",function(t,n,a,r,o){return t.debug("Entitlement"),n.extend({all:function(e,t){return a.all(this.processFilters(e),t).then(function(e){return e.map(function(e){return r.init(e,!0)})})},breakdown:function(t,n){return a.breakdown(t).then(function(t){return n?(n.map(function(n){var a=e.find(t,function(e){return e.id===n.id});return a&&(n.breakdown=a.breakdown),n}),n):t.map(function(e){return r.init(e,!0)})})},logs:function(t){return t=e.cloneDeep(t||{}),t.contact_id&&(t["entitlement_id.contact_id"]=t.contact_id,delete t.contact_id),t.period_id&&(t["entitlement_id.period_id"]=t.period_id,delete t.period_id),t.return=t.return||[],t.return.push("entitlement_id","entitlement_id.type_id","editor_id","entitlement_amount","comment","created_date"),o.all(t)}})}])}),define("leave-absences/shared/apis/leave-request.api",["leave-absences/shared/modules/apis","common/lodash","common/services/api"],function(e,t){"use strict";e.factory("LeaveRequestAPI",["$log","api","$q","shared-settings",function(e,n,a){return e.debug("LeaveRequestAPI"),n.extend({all:function(t,n,r,o,s){e.debug("LeaveRequestAPI.all");var i=a.defer();return t&&t.contact_id&&t.contact_id.IN&&0===t.contact_id.IN.length?i.resolve({list:[],total:0,allIds:[]}):i.resolve(this.getAll("LeaveRequest",t,n,r,o,"getFull",s)),i.promise},balanceChangeByAbsenceType:function(t,n,r,o){e.debug("LeaveRequestAPI.balanceChangeByAbsenceType");var s=a.defer();t&&n||s.reject("contact_id and period_id are mandatory");var i={contact_id:t,period_id:n,statuses:r?{IN:r}:null,public_holiday:o||!1};return this.sendGET("LeaveRequest","getbalancechangebyabsencetype",i,!1).then(function(e){s.resolve(e.values)}),s.promise},calculateBalanceChange:function(n){return e.debug("LeaveRequestAPI.calculateBalanceChange",n),this.sendPOST("LeaveRequest","calculatebalancechange",n).then(function(e){return e.values.breakdown=t.values(e.values.breakdown),e.values})},getBalanceChangeBreakdown:function(e){return this.sendGET("LeaveRequest","getBreakdown",{leave_request_id:e},!1)},getWorkDayForDate:function(e,t){return this.sendGET("LeaveRequest","getWorkDayForDate",{leave_date:e,contact_id:t.toString()},!1)},create:function(t){return e.debug("LeaveRequestAPI.create",t),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})},delete:function(e){return this.sendPOST("LeaveRequest","delete",{id:e})},deleteAttachment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,attachment_id:n}),this.sendPOST("LeaveRequest","deleteattachment",a).then(function(e){return e.values})},deleteComment:function(e,n){return n=t.assign({},n,{comment_id:e}),this.sendPOST("LeaveRequest","deletecomment",n).then(function(e){return e.values})},find:function(t){return e.debug("LeaveRequestAPI.find"),this.sendGET("LeaveRequest","getFull",{id:t}).then(function(e){return 0===e.values.length?a.reject("LeaveRequest not found with this ID"):e.values[0]})},getAttachments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getattachments",n,!1).then(function(e){return e.values})},getComments:function(e,n){return n=t.assign({},n,{leave_request_id:e}),this.sendGET("LeaveRequest","getcomment",n,!1).then(function(e){return e.values})},isManagedBy:function(t,n){return e.debug("LeaveRequestAPI.isManagedBy"),this.sendPOST("LeaveRequest","isManagedBy",{leave_request_id:t,contact_id:n}).then(function(e){return e.values})},isValid:function(n){e.debug("LeaveRequestAPI.isValid",n);var r=a.defer();return this.sendPOST("LeaveRequest","isValid",n).then(function(e){e.count>0?r.reject(t(e.values).map().flatten().value()):r.resolve(e.values)}),r.promise},saveComment:function(e,n,a){return a=t.assign({},a,{leave_request_id:e,text:n.text,contact_id:n.contact_id}),this.sendPOST("LeaveRequest","addcomment",a).then(function(e){return e.values})},update:function(t){e.debug("LeaveRequestAPI.update",t);var n=a.defer();return t.id||n.reject("id is mandatory field"),this.sendPOST("LeaveRequest","create",t).then(function(e){return e.values[0]})}})}])}),define("leave-absences/shared/instances/leave-request.instance",["common/lodash","common/moment","leave-absences/shared/modules/models-instances","common/models/option-group","common/models/instances/instance","leave-absences/shared/models/absence-type.model"],function(e,t,n){"use strict";n.factory("LeaveRequestInstance",["$q","checkPermissions","OptionGroup","shared-settings","ModelInstance","LeaveRequestAPI","AbsenceType",function(n,a,r,o,s,i,u){function c(e){return p(e).then(function(e){var t=this.status_id;return this.status_id=e.value,this.update().catch(function(e){return this.status_id=t,n.reject(e)}.bind(this))}.bind(this))}function l(){return u.all({id:this.type_id}).then(u.loadCalculationUnits).then(function(e){return n.all({calculatedBalanceChange:this.calculateBalanceChange(e[0].calculation_unit_name),currentBalanceChange:this.getBalanceChangeBreakdown()})}.bind(this)).then(function(e){return+e.currentBalanceChange.amount!=+e.calculatedBalanceChange.amount})}function d(e){return p(e).then(function(e){return this.status_id===e.value}.bind(this))}function m(){var t=[];return e.forEach(this.files,function(e){e.toBeDeleted&&t.push(i.deleteAttachment(this.id,e.attachment_id))}.bind(this)),n.all(t)}function f(e){return t.duration(e.time_to).subtract(t.duration(e.time_from)).asHours()}function p(t){return r.valuesOf("hrleaveandabsences_leave_request_status").then(function(n){return e.find(n,function(e){return e.name===t})})}function h(t){var a=e.cloneDeep(t),r=a.breakdown.length>1,o=e.first(e.values(a.breakdown)),s=e.last(e.values(a.breakdown));return n.all([this.getWorkDayForDate(o.date),r&&this.getWorkDayForDate(s.date)]).then(function(t){return o.amount=t[0].time_from?Math.min(this.from_date_amount,f(t[0])):0,r&&(s.amount=t[1].time_from?Math.min(this.to_date_amount,f(t[1])):0),a.amount=-1*e.reduce(a.breakdown,function(e,t){return e+t.amount},0),a}.bind(this))}function v(){var e=this.id,t=[];return t.push(n.sequence(this.comments.filter(function(e){return!e.comment_id}).map(function(t){return function(){return i.saveComment(e,t)}}))),t=t.concat(this.comments.filter(function(e){return e.comment_id&&e.toBeDeleted}).map(function(e){return i.deleteComment(e.comment_id)})),n.all(t)}return s.extend({defaultCustomData:function(){return{comments:[],files:[],request_type:"leave"}},calculateBalanceChange:function(t){var n=["contact_id","from_date","to_date","type_id","from_date_type","to_date_type"];return"hours"===t&&e.pull(n,"from_date_type","to_date_type"),i.calculateBalanceChange(e.pick(this,n)).then(function(e){return"hours"===t?h.call(this,e):e}.bind(this))},cancel:function(){return c.call(this,o.statusNames.cancelled)},approve:function(){return c.call(this,o.statusNames.approved)},checkIfBalanceChangeNeedsRecalculation:function(){return l.call(this)},reject:function(){return c.call(this,o.statusNames.rejected)},sendBack:function(){return c.call(this,o.statusNames.moreInformationRequired)},update:function(){return i.update(this.toAPI()).then(function(){return n.all([v.call(this),m.call(this)])}.bind(this))},create:function(){return i.create(this.toAPI()).then(function(e){return this.id=e.id,n.all([v.call(this)])}.bind(this))},deleteAttachment:function(e){e.toBeDeleted||(e.toBeDeleted=!0)},deleteComment:function(t){if(t.comment_id)return void(t.toBeDeleted=!0);this.comments=e.reject(this.comments,function(e){return t.created_at===e.created_at&&t.text===e.text})},delete:function(){return i.delete(this.id)},getBalanceChangeBreakdown:function(){return i.getBalanceChangeBreakdown(this.id).then(function(t){return{amount:e.reduce(t.values,function(e,t){return e+parseFloat(t.amount)},0),breakdown:t.values.map(function(e){return{amount:Math.abs(parseFloat(e.amount)),date:e.date,type:{id:e.id,value:e.type,label:e.label}}})}})},getWorkDayForDate:function(e){return i.getWorkDayForDate(e,this.contact_id).then(function(e){return e.values}).catch(function(e){return n.reject(e)})},isValid:function(){return i.isValid(this.toAPI())},isApproved:function(){return d.call(this,o.statusNames.approved)},isAwaitingApproval:function(){return d.call(this,o.statusNames.awaitingApproval)},isCancelled:function(){return d.call(this,o.statusNames.cancelled)},isRejected:function(){return d.call(this,o.statusNames.rejected)},isSentBack:function(){return d.call(this,o.statusNames.moreInformationRequired)},loadComments:function(){return this.id?i.getComments(this.id).then(function(e){this.comments=e}.bind(this)):n.resolve()},roleOf:function(e){return this.contact_id===e?n.resolve("owner"):a(o.permissions.admin.administer).then(function(t){return t?"admin":i.isManagedBy(this.id,e).then(function(e){return e?"manager":"none"})}.bind(this))},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])},loadAttachments:function(){return this.id?i.getAttachments(this.id).then(function(e){this.files=e}.bind(this)):n.resolve()}})}])}),define("leave-absences/shared/models/leave-request.model",["leave-absences/shared/modules/models","common/models/model","leave-absences/shared/apis/leave-request.api","leave-absences/shared/instances/leave-request.instance"],function(e){"use strict";e.factory("LeaveRequest",["$log","Model","LeaveRequestAPI","LeaveRequestInstance",function(e,t,n,a){return e.debug("LeaveRequest"),t.extend({all:function(e,t,r,o,s){return n.all(this.processFilters(e),t,r,o,s).then(function(e){return e.list=e.list.map(function(e){return a.init(e,!0)}),e})},balanceChangeByAbsenceType:function(e,t,a,r){return n.balanceChangeByAbsenceType(e,t,a,r)},find:function(e){return n.find(e).then(function(e){return a.init(e,!0)})}})}])}),define("leave-absences/shared/apis/public-holiday.api",["leave-absences/shared/modules/apis","common/services/api"],function(e){"use strict";e.factory("PublicHolidayAPI",["$log","api",function(e,t){return e.debug("PublicHolidayAPI"),t.extend({all:function(t){return e.debug("PublicHolidayAPI"),this.sendGET("PublicHoliday","get",t).then(function(e){return e.values})}})}])}),define("leave-absences/shared/instances/public-holiday.instance",["leave-absences/shared/modules/models-instances","common/models/instances/instance"],function(e){"use strict";e.factory("PublicHolidayInstance",["$log","ModelInstance",function(e,t){return e.debug("PublicHolidayInstance"),t.extend({})}])}),define("leave-absences/shared/models/public-holiday.model",["common/moment","leave-absences/shared/modules/models","common/models/model","common/services/hr-settings","leave-absences/shared/apis/public-holiday.api","leave-absences/shared/instances/public-holiday.instance"],function(e,t){"use strict";t.factory("PublicHoliday",["$log","Model","PublicHolidayAPI","PublicHolidayInstance","shared-settings",function(t,n,a,r,o){return t.debug("PublicHoliday"),n.extend({all:function(e){return t.debug("PublicHoliday.all",e),a.all(e).then(function(e){return e.map(function(e){return r.init(e,!0)})})},isPublicHoliday:function(n){t.debug("PublicHoliday.isPublicHoliday",n);var r=e(n).format(o.serverDateFormat),s={date:r};return a.all(s).then(function(e){return!!e.length})}})}])}),define("leave-absences/shared/modules/components",["common/angular","common/modules/directives","common/modules/models","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/models"],function(e){return e.module("leave-absences.components",["common.directives","common.models","leave-absences.settings","leave-absences.models"])}),define("leave-absences/shared/modules/controllers",["common/angular","common/angularBootstrap","leave-absences/shared/modules/models","leave-absences/shared/modules/models-instances","leave-absences/shared/modules/shared-settings"],function(e){return e.module("leave-absences.controllers",["ui.select","leave-absences.models","leave-absences.models.instances","leave-absences.settings"])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers","common/models/contract","common/services/notification.service"],function(e,t,n){function a(n,a,r,o,s,i){function u(){return d().then(function(n){var a=n.filter(function(e){var n=e.info.details;return t(n.period_start_date).isSameOrBefore(v.selectedPeriod.end_date)&&(t(n.period_end_date).isSameOrAfter(v.selectedPeriod.start_date)||!n.period_end_date)});return e.uniq(a.map(function(e){return e.contact_id}))})}function c(){return{loadContacts:function(){var e=v.filters.userSettings.assignedTo.type;return m(e).then(function(e){v.lookupContacts=e}).then(function(){return"me"!==e?u():a.resolve(null)}).then(function(e){return v.contactIdsToReduceTo=e,l()}).then(function(e){return e})}}}function l(){return r.all(f(),null,"display_name").then(function(e){return e.list})}function d(){return h?a.resolve(h):s.all()}function m(e){return"me"===e?r.leaveManagees(v.contactId):"unassigned"===e?r.leaveManagees(void 0,{unassigned:!0}):r.all().then(function(e){return e.list})}function f(){return{department:v.filters.userSettings.department?v.filters.userSettings.department.value:null,level_type:v.filters.userSettings.level_type?v.filters.userSettings.level_type.value:null,location:v.filters.userSettings.location?v.filters.userSettings.location.value:null,region:v.filters.userSettings.region?v.filters.userSettings.region.value:null,id:{IN:v.filters.userSettings.contact?[v.filters.userSettings.contact.id]:v.lookupContacts.map(function(e){return e.id})}}}function p(e){i.info("",["

    When All filter is selected, all staff members with contracts which are active in the selected absence period are displayed.

    ","

    People I approve filter displays only staff members who you approve leave for.

    ","

    People without approver filter displays all staff members with contracts which are active in the selected absence period and who do not have any leave approver assigned.

    "].join(""))}n.debug("LeaveCalendarAdminController");var h,v;return{init:function(e){return v=e,v.showContactDetailsLink=!0,v.showContactName=!0,v.showFilters=!0,v.filtersByAssignee=[{type:"me",label:"People I approve"},{type:"unassigned",label:"People without approver"},{type:"all",label:"All"}],v.filters.userSettings.assignedTo=v.filtersByAssignee[0],v.showAdminFilteringHint=p,c()}}}n.controller("LeaveCalendarAdminController",["$log","$q","Contact","ContactInstance","Contract","notificationService",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t,n){function a(){return{loadContacts:function(){return n.init({id:s.contactId}).leaveManagees().then(function(e){s.lookupContacts=e}).then(r)}}}function r(){return t.all(o(),null,"display_name").then(function(e){return e.list})}function o(){return{department:s.filters.userSettings.department?s.filters.userSettings.department.value:null,level_type:s.filters.userSettings.level_type?s.filters.userSettings.level_type.value:null,location:s.filters.userSettings.location?s.filters.userSettings.location.value:null,region:s.filters.userSettings.region?s.filters.userSettings.region.value:null,id:{IN:s.filters.userSettings.contact?[s.filters.userSettings.contact.id]:s.lookupContacts.map(function(e){return e.id})}}}e.debug("LeaveCalendarManagerController");var s;return{init:function(e){return s=e,s.showContactName=!0,s.showFilters=!0,a()}}}n.controller("LeaveCalendarManagerController",["$log","Contact","ContactInstance",a])}),define("leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(e,t){function n(){return{loadContacts:function(){return t.all({id:{in:[a.contactId]}}).then(function(e){return e.list})}}}e.debug("LeaveCalendarStaffController");var a;return{init:function(e){return a=e,a.filters.userSettings.contacts_with_leaves=!1,n()}}}n.controller("LeaveCalendarStaffController",["$log","Contact",a])}),define("leave-absences/shared/components/leave-calendar.component",["common/angular","common/lodash","common/moment","leave-absences/shared/modules/components","leave-absences/shared/controllers/sub-controllers/leave-calendar-admin.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-manager.controller","leave-absences/shared/controllers/sub-controllers/leave-calendar-staff.controller"],function(e,t,n,a){function r(a,r,o,s,i,u,c,l,d,m){function f(){for(var e=[],t=n(E.selectedPeriod.start_date).clone().startOf("month"),a=n(E.selectedPeriod.end_date).clone().endOf("month");t.isBefore(a);)e.push(P(t)),t.add(1,"month");E.months=e}function p(){s.$new().$watch(function(){return E.selectedMonths},function(t,n){null===n||e.equals(t,n)||T()})}function h(e){E.injectMonths=!0,O("injected").then(function(){T(e)}).then(function(){E.loading.calendar=!1})}function v(){I=a("LeaveCalendar"+t.capitalize(x)+"Controller").init(E)}function g(e){return e.current?"Current Period ("+e.title+")":e.title}function b(){return u.all().then(function(e){E.absencePeriods=t.sortBy(e,"start_date"),E.selectedPeriod=t.find(E.absencePeriods,function(e){return!!e.current})}).then(f).then(S)}function y(){return c.all().then(c.loadCalculationUnits)}function _(){return d.valuesOf(["hrleaveandabsences_absence_type_calculation_unit","hrleaveandabsences_leave_request_day_type","hrleaveandabsences_leave_request_status","hrleaveandabsences_toil_amounts"])}function q(){return I.loadContacts().then(function(e){E.contacts=e})}function $(){return d.valuesOf(["hrjc_region","hrjc_location","hrjc_level_type","hrjc_department"]).then(function(e){E.filters.optionValues.regions=e.hrjc_region,E.filters.optionValues.locations=e.hrjc_location,E.filters.optionValues.levelTypes=e.hrjc_level_type,E.filters.optionValues.departments=e.hrjc_department})}function w(){return l.all()}function C(){return r.all([y(),w(),_()]).then(function(e){E.supportData.absenceTypes=e[0],E.supportData.publicHolidays=e[1],E.supportData.calculationUnits=e[2].hrleaveandabsences_absence_type_calculation_unit,E.supportData.dayTypes=e[2].hrleaveandabsences_leave_request_day_type,E.supportData.leaveRequestStatuses=e[2].hrleaveandabsences_leave_request_status,E.supportData.toilAmounts=t.indexBy(e[2].hrleaveandabsences_toil_amounts,"value")})}function A(){var e=r.resolve();return E.injectMonths&&(e=O("destroyed"),E.injectMonths=!1),e}function P(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),shortName:e.format("MMM")}}function D(e){ +e=t.includes(["contacts","period"],e)?e:"period",r.resolve().then(function(){E.loading.calendar=!0}).then(A).then("period"===e?f:t.noop).then("contacts"===e?q:t.noop).then(function(){h("contacts"===e)})}function T(e){var n=E.selectedMonths.length?E.months.filter(function(e){return t.includes(E.selectedMonths,e.index)}):E.months;s.$emit("LeaveCalendar::showMonths",n,!!e)}function S(){E.selectedMonths=[n().month()]}function R(){return E.roleOverride?r.resolve().then(function(){x=E.roleOverride}):r.all([m(i.permissions.admin.administer),m(i.permissions.ssp.manage)]).then(function(e){x=e[0]?"admin":e[1]?"manager":"staff"})}function O(e){return r(function(n){var a=0,r=s.$on("LeaveCalendar::month"+t.capitalize(e),function(){++a===E.months.length&&(r(),n())})})}o.debug("Component: leave-calendar");var I,x,E=this;E.absencePeriods=[],E.contacts=[],E.contactIdsToReduceTo=null,E.injectMonths=!1,E.months=[],E.selectedMonths=null,E.selectedPeriod=null,E.showContactName=!1,E.showFilters=!1,E.supportData={},E.loading={calendar:!0,page:!0},E.filters={optionValues:{},userSettings:{contact:null,contacts_with_leaves:!0,department:null,level_type:null,location:null,region:null}},E.labelPeriod=g,E.refresh=D,function(){R().then(p).then(v).then(A).then(b).then(function(){return r.all([q(),C()])}).then(function(){return E.showFilters?$():t.noop}).then(function(){h()}).then(function(){E.loading.page=!1})}()}a.component("leaveCalendar",{bindings:{contactId:"<",roleOverride:"@?"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar.html"}],controllerAs:"calendar",controller:["$controller","$q","$log","$rootScope","shared-settings","AbsencePeriod","AbsenceType","PublicHoliday","OptionGroup","checkPermissions",r]})}),define("leave-absences/shared/components/leave-calendar-day.component",["common/lodash","common/moment","leave-absences/shared/modules/components"],function(e,t,n){function a(n,a,r,o){"use strict";function s(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function i(e){return e.isAM?"AM":e.isPM?"PM":""}function u(e){var n=t(e.from_date).isSame(g.date,"day"),a=t(e.to_date).isSame(g.date,"day");return n?t(e.from_date).format("HH:mm"):a?t(e.to_date).format("HH:mm"):""}function c(t,n){g.contactData.leaveRequestsAttributes[t.id].absenceTypeTitle=e.find(g.supportData.absenceTypes,{id:t.type_id}).title}function l(t,n){var a=e.find(g.supportData.absenceTypes,{id:t.type_id}),r=e.find(g.supportData.calculationUnits,{value:a.calculation_unit});n.unit=r.name}function d(e,t){t.from_date=new Date(e.from_date),t.to_date=new Date(e.to_date)}function m(t,n){"days"===n.unit&&(n.from_date_type=e.find(g.supportData.dayTypes,{value:t.from_date_type}).label,n.to_date_type=e.find(g.supportData.dayTypes,{value:t.to_date_type}).label)}function f(e,t){var n="";n=t.isAccruedTOIL?"AT":"days"===t.unit?i(t):u(e),t.label=n}function p(e){var t=g.contactData.leaveRequestsAttributes[e.id];[l,m,f,d,c].forEach(function(n){n.call(this,e,t)})}function h(e,t){r(function(){g.tooltip[e+"_hovered"]=t,g.tooltip.show=g.tooltip.day_cell_hovered||g.tooltip.tooltip_hovered},t?0:100)}function v(){a.$watch("day.contactData.leaveRequests",function(){g.contactData&&g.contactData.leaveRequests&&g.contactData.leaveRequests.forEach(p)},!0)}n.debug("Component: leave-calendar-day");var g=this;g.tooltip={show:!1,day_cell_hovered:!1,tooltip_hovered:!1},g.openLeavePopup=s,g.toggleTooltip=h,function(){v()}()}n.component("leaveCalendarDay",{bindings:{contactData:"<",date:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-day.html"}],controllerAs:"day",controller:a}),a.$inject=["$log","$scope","$timeout","LeavePopup"]}),define("leave-absences/shared/components/leave-calendar-legend.component",["leave-absences/shared/modules/components"],function(e){function t(e){function t(e){return{backgroundColor:e.color,borderColor:e.color}}e.debug("Component: leave-calendar-legend");var n=this;n.legendCollapsed=!0,n.getAbsenceTypeStyle=t}e.component("leaveCalendarLegend",{bindings:{absenceTypes:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-legend.html"}],controllerAs:"legend",controller:["$log",t]})}),define("leave-absences/shared/components/leave-calendar-month.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(e){q([e]),U(e)}function l(e){return{index:e.month(),year:e.year(),name:e.format("MMMM"),loading:!0,days:d(e)}}function d(n){var a=t(),r=n.clone().startOf("month");return e.map(e.times(n.daysInMonth()),function(){var e={date:r.format("YYYY-MM-DD"),name:r.format("ddd"),index:r.format("D"),current:a.isSame(r,"day"),enabled:r.isSameOrAfter(Y.period.start_date)&&r.isSameOrBefore(Y.period.end_date),contactsData:{}};return r.add(1,"day"),e})}function m(e){return V[e]}function f(){return Y.showOnlyWithLeaveRequests?Y.contacts.filter(function(e){return Object.keys(G[e.id]||{}).length}):Y.contacts}function p(e){return t(e,u.serverDateFormat)}function h(e){var t=g(e);t&&(E(t),U(t))}function v(t){var n={request_type:"toil"};return e.some(t,n)&&!e.every(t,n)?e.filter(t,n):t}function g(t){var n;return e.find(G[t.contact_id],function(a){return n=e.find(a,function(e){return+e.id==+t.id})}),n}function b(e){return CRM.url("civicrm/contact/view",{cid:e})}function y(e,n){var a={};return n.forEach(function(n){a[n.id]={styles:N(n),isAccruedTOIL:C(n,"toil"),isRequested:P(n),isAM:w("half_day_am",n,e.date),isPM:w("half_day_pm",n,e.date),isSingleDay:t(n.from_date).isSame(n.to_date,"day")}}),a}function _(){Y.supportData.dayTypes=e.indexBy(Y.supportData.dayTypes,"name"),Y.supportData.leaveRequestStatuses=e.indexBy(Y.supportData.leaveRequestStatuses,"value"),Y.supportData.publicHolidays=e.transform(Y.supportData.publicHolidays,function(e,t){e[p(t.date).valueOf()]=t},{})}function q(e){return e.forEach(function(e){var t=D(e);G[e.contact_id]=G[e.contact_id]||{},t.forEach(function(t){G[e.contact_id][t.date]||(G[e.contact_id][t.date]=[]),G[e.contact_id][t.date].push(e)})}),a.resolve()}function $(){W.push(r.$on("LeaveCalendar::showMonths",j)),W.push(i.subscribe("LeaveRequest::new",c)),W.push(i.subscribe("LeaveRequest::edit",F)),W.push(i.subscribe("LeaveRequest::updatedByManager",F)),W.push(i.subscribe("LeaveRequest::delete",h)),W.push(i.subscribe("LeaveRequest::statusUpdate",function(e){"delete"===e.status?h(e.leaveRequest):F(e.leaveRequest)}))}function w(e,n,a){var r=Y.supportData.dayTypes[e];return t(a).isSame(n.from_date,"day")?r.value===n.from_date_type:t(a).isSame(n.to_date,"day")?r.value===n.to_date_type:void 0}function C(e,t){return e.request_type===t}function A(e){return!!Y.supportData.publicHolidays[p(e).valueOf()]}function P(t){var n=Y.supportData.leaveRequestStatuses[t.status_id].name;return e.contains([u.statusNames.awaitingApproval,u.statusNames.moreInformationRequired],n)}function D(n){for(var a=[],r=t(n.from_date).clone(),o=t(n.to_date);r.isSameOrBefore(o);)r.month()===Y.month.index&&r.year()===Y.month.year&&a.push(e.find(Y.month.days,function(e){return e.date===r.format("YYYY-MM-DD")})),r.add(1,"day");return a}function T(t){var n=e.find(Y.supportData.leaveRequestStatuses,function(e){return e.name===t});return n?n.value:null}function S(){return[T(u.statusNames.approved),T(u.statusNames.adminApproved),T(u.statusNames.awaitingApproval),T(u.statusNames.moreInformationRequired)]}function R(){return Y.month.loading=!0,a.all([I(),O()]).then(x).then(k).then(function(){H=!0,Y.month.loading=!1})}function O(){return s.all({from_date:{to:Y.month.days[Y.month.days.length-1].date},to_date:{from:Y.month.days[0].date},status_id:{IN:S()},contact_id:{IN:Y.contacts.map(function(e){return e.id})},type_id:{IN:e.pluck(Y.supportData.absenceTypes,"id")}},null,null,null,!1).then(function(e){return q(e.list)})}function I(){var t=Y.month.days[0].date,n=Y.month.days[Y.month.days.length-1].date;return o.get(Y.contacts.map(function(e){return e.id}),t,n).then(function(t){V=e.indexBy(t,"contact_id")})}function x(){return Y.contactIdsToReduceTo&&(Y.contacts=Y.contacts.filter(function(t){return e.includes(Y.contactIdsToReduceTo,t.contact_id)||e.find(G,function(e){return e.contact_id===t.contact_id})})),a.resolve()}function E(t){var n=D(t);G[t.contact_id]=G[t.contact_id]||{},n.forEach(function(n){e.remove(G[t.contact_id][n.date],function(e){return e.id===t.id})})}function L(){r.$emit("LeaveCalendar::monthDestroyed"),W.map(function(e){e.remove?e.remove():e()})}function M(t,n,r){var o,s;return t.contactsData[n]=t.contactsData[n]||{},s=m(n),o=!0===r?a.resolve():a.all([s.isWeekend(p(t.date)),s.isNonWorkingDay(p(t.date))]).then(function(a){e.assign(t.contactsData[n],{isWeekend:a[0],isNonWorkingDay:a[1],isPublicHoliday:A(t.date)})}),o.then(function(){return G[n]&&G[n][t.date]?G[n][t.date]:[]}).then(function(a){a=B(a),e.assign(t.contactsData[n],{leaveRequests:a,leaveRequestsToShowInCell:v(a),leaveRequestsAttributes:y(t,a)})})}function k(){return a.all(Y.month.days.map(function(e){return a.all(Y.contacts.map(function(t){return M(e,t.id)}))}))}function j(t,n,a){!e.find(n,function(e){return e.index===Y.month.index})?Y.visible=!1:(Y.currentPage=0,Y.visible=!0,(a||!H)&&R())}function B(n){return e.sortBy(n,function(e){return+t(e.from_date).format("X")+(w("half_day_pm",e,e.from_date)?1:0)})}function N(t){var n=e.find(Y.supportData.absenceTypes,function(e){return e.id===t.type_id});return t.balance_change>0?{borderColor:n.color}:{borderColor:n.color,backgroundColor:n.color}}function F(e){h(e),-1!==S().indexOf(e.status_id)&&c(e)}function U(e){return a.all(D(e).map(function(t){return M(t,e.contact_id,!0)}))}n.debug("Component: leave-calendar-month");var H=!1,W=[],V={},G={},Y=this;Y.currentPage=0,Y.pageSize=20,Y.visible=!1,Y.showContactName=!!Y.showContactName,Y.showOnlyWithLeaveRequests=!!Y.showOnlyWithLeaveRequests,Y.$onDestroy=L,Y.contactsList=f,Y.getContactUrl=b,function(){var e=t().month(Y.month.index).year(Y.month.year);_(),$(),Y.month=l(e),r.$emit("LeaveCalendar::monthInjected")}()}n.component("leaveCalendarMonth",{bindings:{contacts:"<",contactIdsToReduceTo:"<",month:"<",period:"<",showContactName:"<",showContactDetailsLink:"<",showOnlyWithLeaveRequests:"<",supportData:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-calendar-month.html"}],controllerAs:"month",controller:["$log","$q","$rootScope","Calendar","LeaveRequest","pubSub","shared-settings",a]})}),define("leave-absences/shared/modules/services",["common/angular","common/modules/services"],function(e){"use strict";return e.module("leave-absences.services",["common.services"])}),define("leave-absences/shared/services/leave-request.service",["common/lodash","leave-absences/shared/modules/services"],function(e,t){"use strict";function n(t,n,a){function r(){var t=n.defer();return a.open(e.defaults(o(),{onConfirm:function(){t.resolve(!0)}})),t.promise}function o(){return{title:"Recalculate Balance Change?",copyCancel:"Cancel",copyConfirm:"Yes",classConfirm:"btn-warning",msg:"The leave balance change has updated since this leave request was created. Do you want to recalculate the balance change?"}}return t.debug("LeaveRequest"),{getBalanceChangeRecalculationPromptOptions:o,promptBalanceChangeRecalculation:r}}t.factory("LeaveRequestService",n),n.$inject=["$log","$q","dialog"]}),define("leave-absences/shared/components/leave-request-actions.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/services/notification.service","common/services/pub-sub","leave-absences/shared/services/leave-request.service"],function(e,t,n){function a(n,a,r,o,s,i,u,c){function l(t){_=q.leaveRequest.status_id,e.includes(["cancel","reject","delete"],t)||"toil"===q.leaveRequest.request_type?r.open(h(t)):f(t)}function d(){return"admin"===q.role&&"public_holiday"===q.leaveRequest.request_type}function m(n){var a=q.absenceTypes[q.leaveRequest.type_id].allow_request_cancelation;return"admin"===q.role||("manager"===q.role?e.includes([$.awaitingApproval,$.moreInformationRequired],n):"3"===a?t().isBefore(q.leaveRequest.from_date):"2"===a)}function f(t){r.open({title:"Verifying balance...",loading:!0,optionsPromise:function(){return q.leaveRequest.checkIfBalanceChangeNeedsRecalculation().then(function(n){return n?e.assign(s.getBalanceChangeRecalculationPromptOptions(),{onCloseAfterConfirm:function(){o.openModal(q.leaveRequest,q.leaveRequest.request_type,q.leaveRequest.contact_id,"my-leave"===a.section,!0)}}):h(t)})}})}function p(){e.isArray(q.leaveRequestStatuses)&&(q.leaveRequestStatuses=e.indexBy(q.leaveRequestStatuses,"value")),e.isArray(q.absenceTypes)&&(q.absenceTypes=e.indexBy(q.absenceTypes,"id"))}function h(e){var t=w[e].dialog;return{title:"Confirm "+t.title+"?",copyCancel:"Cancel",copyConfirm:t.btnLabel,classConfirm:"btn-"+t.btnClass,msg:t.msg,onConfirm:function(){return q.leaveRequest[e]().then(function(){g(e)}).catch(function(e){c.error("Error:",e)})}}}function v(e,t,n,a,r){e.stopPropagation(),o.openModal(t,n,a,r)}function g(t){var n=e.find(q.leaveRequestStatuses,function(e){return e.name===u.statusNames.awaitingApproval}).value;_===n&&i.publish("ManagerBadge:: Update Count"),i.publish("LeaveRequest::statusUpdate",{status:t,leaveRequest:q.leaveRequest})}function b(){var t=q.leaveRequestStatuses[q.leaveRequest.status_id].name,n=e.compact(e.map(w,function(n,a){return e.includes(n.allowedStatuses,t)?a:null}));!m(t)&&e.pull(n,"cancel"),"admin"!==q.role&&e.pull(n,"delete"),"staff"===q.role&&e.pull(n,"approve","reject"),"staff"!==q.role&&y(n),d()&&n.push("delete"),q.allowedActions=e.map(n,function(e){return{key:e,label:w[e].label,isDirectAction:w[e].isDirectAction}})}function y(t){e.each(t,function(n,a){"edit"===n&&(t[a]="respond"),e.includes(["respond","view"],n)&&(t[a]="edit")})}n.debug("Component: leave-request-action-dropdown");var _,q=this,$=u.statusNames,w={edit:{label:"Edit",allowedStatuses:[$.awaitingApproval]},respond:{label:"Respond",allowedStatuses:[$.moreInformationRequired]},view:{label:"View",allowedStatuses:[$.approved,$.rejected,$.cancelled]},approve:{label:"Approve",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Approval",btnClass:"success",btnLabel:"Approve",msg:"Please confirm approval"}},reject:{label:"Reject",isDirectAction:!0,allowedStatuses:[$.awaitingApproval],dialog:{title:"Rejection",btnClass:"warning",btnLabel:"Reject",msg:"Please confirm rejection"}},cancel:{label:"Cancel",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.approved,$.rejected,$.moreInformationRequired],dialog:{title:"Cancellation",btnClass:"danger",btnLabel:"Confirm",msg:"Please confirm cancellation"}},delete:{label:"Delete",isDirectAction:!0,allowedStatuses:[$.awaitingApproval,$.moreInformationRequired,$.approved,$.rejected,$.cancelled],dialog:{title:"Deletion",btnClass:"danger",btnLabel:"Confirm",msg:"This cannot be undone"}}};q.allowedActions=[],q.action=l,q.openLeavePopup=v,function(){p(),b()}()}n.component("leaveRequestActions",{bindings:{leaveRequest:"<",leaveRequestStatuses:"<",absenceTypes:"<",role:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-actions.html"}],controllerAs:"actions",controller:a}),a.$inject=["$log","$rootScope","dialog","LeavePopup","LeaveRequestService","pubSub","shared-settings","notificationService"]}),define("leave-absences/shared/components/leave-request-popup-comments-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/hr-settings","common/models/session.model"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){q.request.comments.push({contact_id:_,leave_request_id:q.request.id,text:q.comment.text}),q.comment.text=""}function l(){return q.comment.text.length>0}function d(e){return!e.comment_id||q.canManage}function m(e){return t.utc(e,s.serverDateTimeFormat).local().format(o.DATE_FORMAT.toUpperCase()+" HH:mm")}function f(){return q.request.comments.filter(function(e){return!e.toBeDeleted})}function p(e){return e===_?"Me":q.comment.contacts[e]?q.comment.contacts[e].display_name:void 0}function h(e){return q.mode===e}function v(){q.comment.text.length&&q.addComment()}function g(){var t=e.indexBy(q.request.comments,"contact_id"),n=Object.keys(t);return i.all({id:{IN:n}},{page:1,size:0}).then(function(t){q.comment.contacts=e.indexBy(t.list,"contact_id")})}function b(){return q.request.loadComments().then(function(){a.$broadcast("LeaveRequestPopup::requestObjectUpdated"),q.request.comments.length&&g()})}function y(){return q.loading.component=!0,u.get().then(function(e){_=e.contactId}).then(function(){q.loading.component=!1})}n.debug("Component: leave-request-popup-comments-tab");var _=null,q=this;q.loading={component:!0},q.comment={text:"",contacts:{}},q.addComment=c,q.canRemoveComment=d,q.canSubmit=l,q.formatDateTime=m,q.getActiveComments=f,q.getCommentorName=p,q.isMode=h,q.onBeforeSubmit=v,function(){r.$emit("LeaveRequestPopup::addTab",q),b(),y()}()}n.component("leaveRequestPopupCommentsTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-comments-tab.html"}],controllerAs:"commentsCtrl",controller:["$log","$rootScope","$scope","HR_settings","shared-settings","Contact","Session",a]})}),define("leave-absences/shared/components/leave-request-popup-details-tab.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/models/session.model","leave-absences/shared/models/calendar.model"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l,d,m){function f(){te.balance.closing=te.balance.opening+te.balance.change.amount}function p(e){return t(e,u.serverDateFormat).toDate()}function h(e){return t(e).format(u.serverDateFormat)}function v(e){var t;return s.resolve().then(function(){F(e),"from"===e&&N(),O("hours")&&(y(e),"from"!==e||te.uiOptions.multipleDays||y("to")),te.loading[e+"DayTypes"]=!0}).then(function(){return q(e)}).then(function(e){if(t=e.id!==te.period.id,t&&(te.period=e),!te.period.id)return s.reject("Please change date as it is not in any absence period")}).then(H).then(function(){if(t)return L()}).then(function(){return te.onDateChangeExtended&&te.onDateChangeExtended(e)}).then(function(){if(Y(),!t)return k();r.$broadcast("LeaveRequestPopup::absencePeriodChanged")}).catch(A).finally(_)}function g(){return Y(),k()}function b(){return te.uiOptions.toDate=null,F("to"),s.resolve().then(Y).then(te.setDaysSelectionModeExtended).then(_).then(!te.uiOptions.multipleDays&&k)}function y(e){te.uiOptions.times[e].loading=!0}function _(){["from","to"].forEach(function(e){te.loading[e+"DayTypes"]=!1,O("hours")&&(te.uiOptions.times[e].loading=!1)})}function q(n){var a=t(te.uiOptions[n+"Date"]).format(te.uiOptions.userDateFormat.toUpperCase());return e.find(te.absencePeriods,function(e){return e.isInPeriod(a)})||{}}function $(){return te.request?te.request.request_type:te.leaveType||null}function w(e){return t().set({hours:e.split(":")[0],minutes:e.split(":")[1]})}function C(){return z(),te.loading.balanceChange=!0,te.request.getBalanceChangeBreakdown().then(U).catch(A)}function A(t){r.$broadcast("LeaveRequestPopup::handleError",e.isArray(t)?t:[t]),te.loading.fromDayTypes=!1,te.loading.balanceChange=!1,te.loading.tab=!1,te.loading.toDayTypes=!1}function P(){return te.isMode("create")||te.forceRecalculateBalanceChange?k():C()}function D(){var e=te.request.attributes();return te.uiOptions.fromDate=p(te.request.from_date),te.request.to_date=e.to_date,te.request.to_date_type=e.to_date_type,te.uiOptions.toDate=p(te.request.to_date),te.initDayTypesExtended?te.initDayTypesExtended():s.resolve()}function T(){ee.push(r.$on("LeaveRequestPopup::absenceTypeChanged",function(){J()}),r.$on("LeaveRequestPopup::absencePeriodBalancesUpdated",function(e,t){K(t)}),r.$on("LeaveRequestPopup::recalculateBalanceChange",k))}function S(){te.isMode("edit")&&(te.isLeaveStatus(u.statusNames.approved)||te.isLeaveStatus(u.statusNames.adminApproved))&&(Z={absenceTypeId:te.request.type_id,value:te.selectedAbsenceType.remainder-te.request.balance_change})}function R(){r.$watch(function(){return te.uiOptions.times.from.time},function(e,t){e!==t&&(te.uiOptions.multipleDays||(Q(e),Y()))})}function O(e){return te.selectedAbsenceType.calculation_unit_name===e}function I(e){return te.request.request_type===e}function x(t){return e.includes(["weekend","non_working_day","public_holiday"],t)}function E(){return l.valuesOf("hrleaveandabsences_leave_request_day_type").then(function(e){te.requestDayTypes=e})}function L(){return c.get(te.request.contact_id,te.period.start_date,te.period.end_date).then(function(e){te.calendar=e})}function M(){var e=(te.pagination.currentPage-1)*te.pagination.numPerPage,t=e+te.pagination.numPerPage;te.pagination.filteredbreakdown=te.balance.change.breakdown.slice(e,t)}function k(){return z(),te.canCalculateChange()?(te.loading.balanceChange=!0,te.request.change_balance=!0,te.calculateBalanceChange().then(U).catch(A).finally(function(){te.loading.balanceChange=!1})):s.resolve()}function j(){te.pagination.totalItems=te.balance.change.breakdown.length,te.pagination.filteredbreakdown=te.balance.change.breakdown,te.pagination.pageChanged()}function B(){return h(te.request.from_date)===h(te.request.to_date)}function N(){te.uiOptions.toDate&&te.uiOptions.fromDate&&te.uiOptions.multipleDays&&t(te.uiOptions.toDate).isSameOrBefore(te.uiOptions.fromDate)&&(te.uiOptions.toDate=null,F("to"))}function F(e){te.resetUIInputsExtended&&te.resetUIInputsExtended(e),Y(),z()}function U(e){te.balance.change=e,te.request.balance_change=e.amount,f(),j(),te.loading.balanceChange=!1}function H(){var e,n,a;te.uiOptions.fromDate?(e=t(te.uiOptions.fromDate).add(1,"day").toDate(),a=e,n=e):(a=p(te.period.start_date),n=te.uiOptions.date.to.options.minDate),te.uiOptions.date.to.options.initDate=n,te.uiOptions.date.to.options.minDate=a,te.uiOptions.date.to.options.maxDate=p(te.period.end_date)}function W(){return!te.isMode("create")&&B()||te.isMode("create")&&(I("sickness")||O("hours"))?te.uiOptions.multipleDays=!1:te.uiOptions.multipleDays=!0,s.resolve().then(te.setDaysSelectionModeExtended)}function V(){Z&&Z.absenceTypeId===te.selectedAbsenceType.id?te.balance.opening=Z.value||0:te.balance.opening=te.selectedAbsenceType.remainder}function G(){te.selectedAbsenceType=e.find(te.absenceTypes,function(e){return e.id===te.request.type_id})}function Y(){var e=te.uiOptions,t=e.times;te.request.from_date=e.fromDate?h(e.fromDate):null,te.request.to_date=e.toDate?h(e.toDate):null,!e.multipleDays&&e.fromDate&&(te.request.to_date=te.request.from_date,te.request.to_date_type=te.request.from_date_type),(O("hours")||I("toil"))&&(te.request.from_date=te.request.from_date&&t.from.time?te.request.from_date+" "+t.from.time:null,te.request.to_date=te.request.to_date&&t.to.time?te.request.to_date+" "+t.to.time:null)}function z(){te.uiOptions.showBalance=te.canCalculateChange()}function X(){e.forEach(ee,function(e){e()})}function J(){var e,t=te.selectedAbsenceType.calculation_unit_name;return G(),e=t!==te.selectedAbsenceType.calculation_unit_name,V(),s.resolve().then(e&&W).then(e&&te.onAbsenceTypeUpdateExtended).then(e&&Y).then(_).then(k)}function K(e){return te.absenceTypes=e,G(),t(te.uiOptions.toDate).isAfter(te.period.end_date)&&(te.uiOptions.toDate=void 0,F("to")),V(),k()}function Q(e){var t=w(e).add(te.uiOptions.time_interval,"minutes");t.isAfter(w(te.uiOptions.times.to.max))||(te.uiOptions.times.to.min=t.format("HH:mm"),t.isAfter(w(te.uiOptions.times.to.time))&&(te.uiOptions.times.to.time=""))}a.debug("Component: leave-request-popup-details-tab");var Z=null,ee=[],te=this;te.canManage=!1,te.calendar={},te.errors=[],te.isRequired=!0,te.requestDayTypes=[],te.statusNames=u.statusNames,te.loading={tab:!1,balanceChange:!1,fromDayTypes:!1,toDayTypes:!1},te.pagination={currentPage:1,filteredbreakdown:te.balance.change.breakdown,numPerPage:7,totalItems:te.balance.change.breakdown.length,pageChanged:M},te.uiOptions={isChangeExpanded:!1,multipleDays:!0,userDateFormat:i.DATE_FORMAT,showBalance:!1,date:{from:{show:!1,options:{startingDay:1,showWeeks:!1}},to:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}},expiry:{show:!1,options:{minDate:null,maxDate:null,startingDay:1,showWeeks:!1}}},times:{from:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""},to:{amount:0,amountExpanded:!1,loading:!1,max:"00:00",maxAmount:0,min:"00:00",time:""}},time_interval:15},te.convertDateFormatFromServer=p,te.convertDateToServerFormat=h,te.dateChangeHandler=v,te.dateTypeChangeHandler=g,te.daysSelectionModeChangeHandler=b,te.disableAndShowLoadingTimeInput=y,te.getMomentDateWithGivenTime=w,te.handleError=A,te.isCalculationUnit=O,te.isLeaveType=I,te.isNotWorkingDay=x,te.performBalanceChangeCalculation=k,te.setRequestDateTimesAndDateTypes=Y,te.updateEndTimeInputMinTime=Q,te.$onDestroy=X,function(){n("RequestModalDetails"+e.capitalize($(te.leaveType,te.request))+"Controller",{detailsController:te}),te.canManage=te.isRole("manager")||te.isRole("admin"),te.loading.tab=!0,o.$emit("LeaveRequestPopup::addTab",te),T(),te.initChildController().then(function(){return s.all([L(),E()])}).then(!te.isMode("create")&&D).then(W).then(function(){if(!te.isMode("create"))return s.resolve().then(te.initTimesExtended).then(Y)}).then(!te.isMode("create")&&H).then(S).then(V).then(P).then(R).then(!te.isMode("view")&&te.initWatchersExtended).catch(A).finally(function(){te.loading.tab=!1})}()}n.component("leaveRequestPopupDetailsTab",{bindings:{absencePeriods:"<",absenceTypes:"<",balance:"=",request:"<",isLeaveStatus:"<",leaveType:"<",isMode:"<",isSelfRecord:"<",period:"=",isRole:"<",selectedAbsenceType:"=",forceRecalculateBalanceChange:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-details-tab.html"}],controllerAs:"detailsTab",controller:a}),a.$inject=["$controller","$log","$rootScope","$scope","$q","HR_settings","shared-settings","Calendar","OptionGroup","LeaveRequest","$timeout"]}),define("leave-absences/shared/components/leave-request-popup-files-tab",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/file-upload","common/services/file-mime-types","common/services/hr-settings"],function(e,t,n){function a(n,a,r,o,s,i,u,c,l){function d(){return R.fileUploader&&R.fileUploader.queue.length>0}function m(){return R.getFilesAmount()0?D.map(function(e){return e.label}).join(", "):""}function q(){return R.request.loadAttachments().then(function(){r.$broadcast("LeaveRequestPopup::requestObjectUpdated")})}function $(){return a.all(D.map(function(e){return l.getMimeTypeFor(e.label).then(function(t){S[e.label]=t})})).catch(function(){S=null})}function w(){return u.valuesOf("safe_file_extension").then(function(e){D=e})}function C(e){return!e.attachment_id||R.canManage}function A(){e.forEach(T,function(e){e()})}function P(e,t){R.fileUploader.queue&&R.fileUploader.queue.length>0?R.fileUploader.uploadAll({entityID:R.request.id}).then(function(){t()}).catch(t):t()}n.debug("Component: leave-request-popup-files-tab");var D=[],T=[],S={},R=Object.create(this);return R.filesLoaded=!1,R.fileUploader=null,R.today=Date.now(),R.userDateFormatWithTime=s.DATE_FORMAT+" HH:mm",R.userDateFormat=s.DATE_FORMAT,R.$onDestroy=A,R.canRemoveAttachment=C,R.canSubmit=d,R.canUploadMore=m,R.formatDateTime=f,R.getAuthorName=p,R.getFilesAmount=h,R.listFileTypes=_,function(){r.$broadcast("LeaveRequestPopup::childComponent::register"),o.$emit("LeaveRequestPopup::addTab",R),b(),a.all([w(),q()]).then(y).finally(function(){R.filesLoaded=!0})}(),R}n.component("leaveRequestPopupFilesTab",{bindings:{canManage:"<",mode:"<",request:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-popup/leave-request-popup-files-tab.html"}],controllerAs:"filesTab",controller:["$log","$q","$rootScope","$scope","HR_settings","shared-settings","OptionGroup","FileUpload","fileMimeTypes",a]})}),define("leave-absences/shared/components/leave-request-record-actions.component",["leave-absences/shared/modules/components","common/services/hr-settings","common/services/before-hash-query-params.service"],function(e){function t(e,t,n){function a(e,n,a,r){t.openModal.apply(t,arguments)}e.debug("Component: leave-request-record-actions");var r,o=this;o.leaveRequestOptions=[{type:"leave",icon:"briefcase",label:"Leave"},{type:"sickness",icon:"stethoscope",label:"Sickness"}],o.openLeavePopup=a,function(){r=n.parse(),r.openModal&&a(null,r.openModal,o.selectedContactId,o.isSelfRecord)}()}e.component("leaveRequestRecordActions",{bindings:{contactId:"<",isSelfRecord:"<",selectedContactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/leave-request-record-actions.html"}],controllerAs:"vm",controller:["$log","LeavePopup","beforeHashQueryParams",t]})}),define("leave-absences/shared/components/staff-leave-report.component",["common/lodash","common/moment","leave-absences/shared/modules/components","common/services/pub-sub"],function(e,t,n){function a(t,n,a,r,o,s,i,u,c,l,d,m){function f(e,t){t.data.push(e),t.dataIndex[e.id]=e}function p(e){k(e),H.sections.other.open&&f(e,H.sections.other)}function h(){Object.values(H.sections).forEach(function(e){e.data=[]})}function v(e){var t=U[e.status];t?t(e.leaveRequest):H.refresh()}function g(t){t.dataIndex=e.indexBy(t.data,"id")}function b(e){return e.current?"Current Period ("+e.title+")":e.title}function y(){return o.all().then(function(t){H.absencePeriods=e.sortBy(t,"start_date"),H.selectedPeriod=e.find(H.absencePeriods,function(e){return!0===e.current})})}function _(){return s.all().then(s.loadCalculationUnits).then(function(t){H.absenceTypes=t,H.absenceTypesIndexed=e.indexBy(t,"id")})}function q(){return D("approved",{status_id:F(m.statusNames.approved)})}function $(){return n.all([u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,null,!0),u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,[F(m.statusNames.approved)]),u.balanceChangeByAbsenceType(H.contactId,H.selectedPeriod.id,[F(m.statusNames.awaitingApproval),F(m.statusNames.moreInformationRequired)])]).then(function(e){H.absenceTypes.forEach(function(t){t.balanceChanges={holidays:e[0][t.id],approved:e[1][t.id],pending:e[2][t.id]}})})}function w(){return i.all({contact_id:H.contactId,period_id:H.selectedPeriod.id},!0).then(function(e){H.entitlements=e}).then(function(){H.absenceTypesFiltered=H.absenceTypes.filter(function(t){var n=e.find(H.entitlements,function(e){return e.type_id===t.id});return t.entitlement=n?n.value:0,t.remainder=n?n.remainder:{current:0,future:0},!(0===t.entitlement&&"1"!==t.allow_overuse&&"1"!==t.allow_accruals_request)})})}function C(){return i.breakdown({contact_id:H.contactId,period_id:H.selectedPeriod.id},H.entitlements).then(function(){return E(H.entitlements)}).then(function(e){H.sections.entitlements.data=e})}function A(){return n.all([i.breakdown({contact_id:H.contactId,period_id:H.selectedPeriod.id,expired:!0}),P({request_type:"toil",expired:!0 +})]).then(function(e){return n.all({expiredBalanceChangesFlatten:E(e[0]),expiredTOILS:L(e[1].list)})}).then(function(t){H.sections.expired.data=t.expiredBalanceChangesFlatten.concat(t.expiredTOILS),H.sections.expired.data=e.sortBy(H.sections.expired.data,"expiry_date")})}function P(t){return u.all(e.assign({contact_id:H.contactId,from_date:{from:H.selectedPeriod.start_date},to_date:{to:H.selectedPeriod.end_date},type_id:{IN:H.absenceTypes.map(function(e){return e.id})}},t),null,"from_date ASC",null,!1)}function D(e,t){return P(t).then(function(t){H.sections[e].data=t.list})}function T(){return n.all(Object.values(H.sections).filter(function(e){return e.open}).map(I))}function S(){return D("other",{status_id:{in:[F(m.statusNames.rejected),F(m.statusNames.cancelled)]}})}function R(){return D("pending",{status_id:{in:[F(m.statusNames.awaitingApproval),F(m.statusNames.moreInformationRequired)]}})}function O(){return D("holidays",{public_holiday:!0})}function I(e){return e.loading=!0,e.loadLeaveRequests().then(g.bind(this,e)).then(function(){e.loading=!1})}function x(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(t){H.leaveRequestStatuses=e.indexBy(t,"value")})}function E(t){return n.resolve().then(function(){return t.map(function(t){var n=e.find(H.entitlements,function(e){return e.id===t.id});return t.breakdown.map(function(t){return e.assign(e.clone(t),{type_id:n.type_id})})})}).then(function(e){return Array.prototype.concat.apply([],e)})}function L(e){return n.resolve().then(function(){return e.map(function(e){return{expiry_date:e.toil_expiry_date,type:{label:"Accrued TOIL"}}})})}function M(){l.subscribe("LeaveRequest::new",function(){H.refresh()}),l.subscribe("LeaveRequest::edit",function(){H.refresh()}),l.subscribe("LeaveRequest::statusUpdate",v),l.subscribe("LeaveRequest::delete",function(e){k(e)})}function k(t){e.forEach(H.sections,function(n,a){n.dataIndex[t.id]&&(e.remove(n.data,function(e){return e.id===t.id}),delete n.dataIndex[t.id],"other"!==a&&j(t,a))})}function j(t,n){var a=["future","current"],r=H.absenceTypesIndexed[t.type_id];"pending"===n&&e.pull(a,"current"),r.balanceChanges[n]-=t.balance_change,a.forEach(function(e){r.remainder[e]-=t.balance_change})}function B(){H.loading.content=!0,n.all([w(),$()]).then(function(){H.loading.content=!1}).then(function(){return n.all([T(),h()])})}function N(e){var t=H.sections[e];t.open=!t.open,t.open&&!t.data.length&&I(t)}function F(t){return e.find(H.leaveRequestStatuses,function(e){return e.name===t}).value}t.debug("Component: staff-leave-report");var U={delete:k,cancel:p},H=this;H.absencePeriods=[],H.absenceTypes=[],H.absenceTypesFiltered=[],H.absenceTypesIndexed={},H.dateFormat=d.DATE_FORMAT,H.leaveRequestStatuses={},H.selectedPeriod=null,H.role="absence-tab"===a.section?"admin":"staff",H.loading={content:!0,page:!0},H.sections={approved:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:q},entitlements:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:C},expired:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:A},holidays:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:O},pending:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:R},other:{open:!1,data:[],dataIndex:{},loading:!1,loadLeaveRequests:S}},H.labelPeriod=b,H.refresh=B,H.toggleSection=N,function(){n.all([x(),_(),y()]).then(function(){H.loading.page=!1}).then(function(){return n.all([w(),$()])}).then(function(){H.loading.content=!1}),M()}()}n.component("staffLeaveReport",{bindings:{contactId:"<"},templateUrl:["shared-settings",function(e){return e.sharedPathTpl+"components/staff-leave-report.html"}],controllerAs:"report",controller:["$log","$q","$rootScope","checkPermissions","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","OptionGroup","pubSub","HR_settings","shared-settings",a]})}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return s.request.calculateBalanceChange(s.selectedAbsenceType.calculation_unit_name)}function l(){var e=s.request,t=!!e.from_date&&!!e.to_date,n=s.selectedAbsenceType.calculation_unit_name;return"days"===n?t=t&&!!e.from_date_type&&!!e.to_date_type:"hours"===n&&(t=t&&!isNaN(+e.from_date_amount)&&!isNaN(+e.to_date_amount)),t}function d(){return s.canCalculateChange()}function m(t,n){var a=s.uiOptions.times[t],r=e.clone(n.time_from),o=e.clone(n.time_to);s.uiOptions.multipleDays||("from"===t&&o&&r&&(o=s.getMomentDateWithGivenTime(o).subtract(s.uiOptions.time_interval,"minutes").format("HH:mm")),"to"===t&&r&&o&&(r=s.getMomentDateWithGivenTime(r).add(s.uiOptions.time_interval,"minutes").format("HH:mm"))),a.min=r||"00:00",a.max=o||"00:00",a.time="to"===t?a.max:a.min}function f(t,n){return t?(t=s.convertDateToServerFormat(t),v(t).then(function(n){return n?s.requestDayTypes.filter(function(e){return"public_holiday"===e.name}):p(t,s.requestDayTypes).then(function(t){return t.length?t:s.requestDayTypes.filter(function(t){return e.includes(["all_day","half_day_am","half_day_pm"],t.name)})})}).then(function(e){return T(n,e),e})):r.reject([])}function p(e,n){return e=t(e),r.all([s.calendar.isNonWorkingDay(e),s.calendar.isWeekend(e)]).then(function(e){return e[0]?"non_working_day":e[1]?"weekend":null}).then(function(e){return e?n.filter(function(t){return t.name===e}):[]})}function h(e,n){return t.duration(n).subtract(t.duration(e)).asHours()}function v(e){return u.all({public_holiday:1,contact_id:s.request.contact_id,from_date:{from:e},to_date:{to:e}}).then(function(e){return!!e.list.length})}function g(){return r.resolve()}function b(){return C(s.uiOptions.fromDate,"from").then(function(){return C(s.uiOptions.toDate,"to")})}function y(e){o.$watch(function(){return s.uiOptions.times[e].amount},function(e,t){s.isCalculationUnit("days")||+e==+t||(s.isRole("staff")&&(s.request.change_balance=!0),O(),s.performBalanceChangeCalculation())})}function _(e){var n=t(s.request[e+"_date"]).format("HH:mm"),a=s.uiOptions.times[e];(h(a.min,n)<=0||h(a.max,n)>=0)&&(n="from"===e?a.min:a.max),s.uiOptions.times[e].time=n}function q(){var e=s.uiOptions.multipleDays?["from","to"]:["from"],t=s.uiOptions.times;if(s.isCalculationUnit("hours"))return r.all(e.map(P)).then(function(){["from","to"].forEach(function(e){_(e),R(e),t[e].amount=Math.min(s.request[e+"_date_amount"],t[e].maxAmount).toString()}),s.uiOptions.multipleDays||s.updateEndTimeInputMinTime(s.uiOptions.times.from.time)}).then(O)}function $(){["from","to"].forEach(function(e){y(e),w(e)})}function w(e){o.$watch(function(){return s.uiOptions.times[e].time},function(t,n){s.isCalculationUnit("days")||t===n||(s.setRequestDateTimesAndDateTypes(),t&&R(e,!0))})}function C(e,t){return f(e,t).then(function(){s.loading[t+"DayTypes"]=!1})}function A(e){return C(s.uiOptions[e+"Date"],e).then(function(){if(s.isCalculationUnit("hours"))return P(e).then(function(){R(e,!0)})})}function P(e){var t=s.uiOptions[e+"Date"],n=!s.uiOptions.multipleDays;return t?s.request.getWorkDayForDate(s.convertDateToServerFormat(t)).then(function(t){x[e]=t,m(e,t),n&&"from"===e&&m("to",t)}).catch(function(t){return x[e]={},s.handleError(t)}).finally(function(){s.uiOptions.times[e].loading=!1,n&&(s.uiOptions.times.to.loading=!1)}):r.resolve()}function D(t){var n=s.uiOptions.times[t];s["request"+e.startCase(t)+"DayTypes"]=[],n.time="",n.min="00:00",n.max="00:00",n.amount="0",n.maxAmount="0"}function T(t,n){var a="request"+e.startCase(t)+"DayTypes";s[a]=n,s.isMode("create")&&(s.request[t+"_date_type"]=s[a][0].value)}function S(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?(s.disableAndShowLoadingTimeInput("from"),!s.uiOptions.multipleDays&&s.disableAndShowLoadingTimeInput("to"),P("from").then(function(){R("from",!0)})):r.resolve()}function R(e,t){var n=s.uiOptions,a=n.multipleDays?e:"from",r=n.times[a],o=n.multipleDays&&"to"===a?r.min:n.times.from.time,i=n.multipleDays&&"from"===a?r.max:n.times.to.time,u=x[a].number_of_hours?h(o,i).toString():"0";r.maxAmount=u,t&&(r.amount=r.maxAmount)}function O(){var e=s.uiOptions.times;s.request.from_date_amount=isNaN(+e.from.amount)?null:e.from.amount,s.request.to_date_amount=isNaN(+e.to.amount)?null:e.to.amount}function I(){return s.isCalculationUnit("hours")&&s.uiOptions.fromDate?P("from").then(function(){R("from",!0)}):r.resolve()}var x={};a.debug("RequestModalDetailsLeaveController"),s.calculateBalanceChange=c,s.canCalculateChange=l,s.canSubmit=d,s.initChildController=g,s.initDayTypesExtended=b,s.initTimesExtended=q,s.initWatchersExtended=$,s.onAbsenceTypeUpdateExtended=I,s.onDateChangeExtended=A,s.resetUIInputsExtended=D,s.setDaysSelectionModeExtended=S}n.controller("RequestModalDetailsLeaveController",a),a.$inject=["$controller","$log","$q","$rootScope","detailsController","PublicHoliday","LeaveRequest"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller",["common/lodash","leave-absences/shared/modules/controllers"],function(e,t){function n(t,n,a,r,o,s,i){function u(){return!(!i.canCalculateChange()||!i.request.sickness_reason)}function c(){return a.all([m(),h(),f(!0)])}function l(t){var n=i.request.getDocumentArray();return!!e.find(n,function(e){return e===t})}function d(t){return!!e.find(i.sicknessDocumentTypes,function(e){return e.value===t})}function m(){return s.valuesOf("hrleaveandabsences_leave_request_required_document").then(function(e){i.sicknessDocumentTypes=e})}function f(t){return s.valuesOf("hrleaveandabsences_sickness_reason",t).then(function(t){i.sicknessReasons=e.indexBy(t,"name")})}function p(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1").on("crmUnload",function(){f(!1)})}function h(){i.showSicknessOptionsEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}n.debug("RequestModalDetailsSicknessController"),t("RequestModalDetailsLeaveController",{detailsController:i}),i.canSubmit=u,i.initChildController=c,i.isChecked=l,i.isDocumentInRequest=d,i.openSicknessReasonOptionsEditor=p}t.controller("RequestModalDetailsSicknessController",n),n.$inject=["$controller","$log","$q","$rootScope","crmAngService","api.optionGroup","detailsController"]}),define("leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller",["common/lodash","common/moment","leave-absences/shared/modules/controllers"],function(e,t,n){function a(n,a,r,o,s,i,u){function c(){return u.balance.change.amount=+u.request.toil_to_accrue,a.resolve(u.balance.change)}function l(){if(!u.request.from_date||!u.request.to_date)return u.uiOptions.max_toil_duration_and_accrual=null,void(u.uiOptions.toil_duration_in_hours=null);u.uiOptions.max_toil_duration_and_accrual=t.duration(t(u.request.to_date).diff(u.request.from_date)).asHours()}function d(){return v().catch(function(e){return e.length&&(u.errors=e),a.reject(e)}).then(function(e){return i.calculateToilExpiryDate(u.request.type_id,e)}).then(function(e){return u.request.toil_expiry_date=e,u.uiOptions.expiryDate=new Date(e),e})}function m(){return!!u.request.toil_to_accrue}function f(){var e=u.uiOptions.multipleDays&&!!u.request.to_date,t=!u.uiOptions.multipleDays&&!!u.request.from_date,n=t||e,a=F.from_date!==u.request.from_date||F.to_date!==u.request.to_date;return u.canDisplayToilExpirationField&&n&&H.hasExpirationFromAdminSettings&&a}function p(){return!!(u.request.from_date&&u.request.to_date&&u.request.toil_duration&&u.request.toil_to_accrue)}function h(){u.request.toil_expiry_date=!1,u.uiOptions.expiryDate=null}function v(){var e=u.uiOptions.multipleDays,t=u.request;return g({hasErrors:e?!t.to_date&&!t.from_date:!t.from_date,label:e?"To Date":"From Date",value:t.to_date})}function g(e){if(e.hasErrors){var n="Please select "+e.label+" to find expiry date";return a.reject([n])}return e.value?a.resolve(t(e.value).format("YYYY-MM-DD")):a.reject([])}function b(){var e=u.isMode("create")&&H.hasExpirationFromAdminSettings,t=H.hasPreviousExpirationDate,n=u.isLeaveType("toil"),a=u.canManage;u.canDisplayToilExpirationField=n&&(a||e||t)}function y(){u.uiOptions.toil_duration_in_hours=u.request.toil_duration/60}function _(){return H.hasPreviousExpirationDate=u.isMode("edit")&&!!u.request.toil_expiry_date,i.canExpire(u.request.type_id).then(function(e){H.hasExpirationFromAdminSettings=e})}function q(){return u.request.to_date_type=u.request.from_date_type="1",_().then(b).then($).then(T)}function $(){u.canManage&&(u.uiOptions.expiryDate=u.convertDateFormatFromServer(u.request.toil_expiry_date))}function w(){r.$watch(function(){return u.request.toil_to_accrue},function(e,t){+e!=+t&&u.performBalanceChangeCalculation()})}function C(){r.$watch(function(){return u.uiOptions.toil_duration_in_hours},function(e,t){e!==t&&u.isCalculationUnit("hours")&&I(),u.request.toil_duration=u.uiOptions.toil_duration_in_hours?60*u.uiOptions.toil_duration_in_hours:null})}function A(){var e=u.uiOptions.times;e.from.time=t(u.request.from_date).format("HH:mm"),e.to.time=t(u.request.to_date).format("HH:mm"),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time)}function P(){["from","to"].forEach(function(e){r.$watch(function(){return u.uiOptions.times[e].time},function(e,t){e!==t&&(u.setRequestDateTimesAndDateTypes(),B(),l(),x())})})}function D(){u.isMode("view")||(w(),C(),P())}function T(t){return s.valuesOf("hrleaveandabsences_toil_amounts",t).then(function(t){u.toilAmounts=e.sortBy(t,function(e){return+e.weight})})}function S(){return l(),x(),B()}function R(){return L(),u.uiOptions.multipleDays||u.updateEndTimeInputMinTime(u.uiOptions.times.from.time),l(),U?U=!1:x(),B()}function O(e){u.uiOptions.times[e].time=""}function I(){u.request.toil_to_accrue=u.uiOptions.toil_duration_in_hours}function x(){u.uiOptions.toil_duration_in_hours=u.uiOptions.max_toil_duration_and_accrual}function E(){F=e.cloneDeep(u.request.attributes())}function L(){u.uiOptions.multipleDays?["from","to"].forEach(function(e){u.uiOptions.times[e].min="00:00",u.uiOptions.times[e].max="23:45"}):(u.uiOptions.times.from.min="00:00",u.uiOptions.times.from.max="23:30",u.uiOptions.times.to.min="00:15",u.uiOptions.times.to.max="23:45")}function M(){u.setRequestDateTimesAndDateTypes(),l(),x(),u.isCalculationUnit("hours")?I():u.request.toil_to_accrue=null}function k(){o.loadForm("/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1").on("crmUnload",function(){T(!1)})}function j(){u.showTOILAccrualsOptionEditorIcon=e.includes(["admin-dashboard","absence-tab"],r.section)}function B(){return f()?d().catch(a.resolve):a.resolve()}function N(){u.uiOptions.expiryDate&&(u.request.toil_expiry_date=u.convertDateToServerFormat(u.uiOptions.expiryDate))}n.debug("RequestModalDetailsToilController");var F,U=!u.isMode("create"),H={hasPreviousExpirationDate:null,hasExpirationFromAdminSettings:null};u.canDisplayToilExpirationField=!1,u.calculateBalanceChange=c,u.canCalculateChange=m,u.canSubmit=p,u.clearExpiryDate=h,u.initChildController=q,u.initTimesExtended=A,u.initWatchersExtended=D,u.onAbsenceTypeUpdateExtended=M,u.onDateChangeExtended=S,u.openToilInDaysAccrualOptionsEditor=k,u.resetUIInputsExtended=O,u.setDaysSelectionModeExtended=R,u.updateExpiryDate=N,function(){E(),L(),j(),!u.isMode("create")&&y()}()}n.controller("RequestModalDetailsToilController",a),a.$inject=["$log","$q","$rootScope","crmAngService","OptionGroup","AbsenceType","detailsController"]}),define("leave-absences/shared/instances/sickness-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("SicknessRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={sickness_reason:null,sickness_required_documents:"",request_type:"sickness"};return e.assign({},n.defaultCustomData(),t)},getDocumentArray:function(){return this.sickness_required_documents?this.sickness_required_documents.split(","):[]},toggleDocument:function(t){var n=this.getDocumentArray(),a=n.indexOf(t);e.contains(n,t)?n.splice(a,1):n.push(t),this.sickness_required_documents=n.join(",")},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/instances/toil-request.instance",["common/lodash","leave-absences/shared/modules/models-instances","leave-absences/shared/instances/leave-request.instance"],function(e,t){"use strict";t.factory("TOILRequestInstance",["LeaveRequestAPI","LeaveRequestInstance",function(t,n){return n.extend({defaultCustomData:function(){var t={from_date_amount:0,to_date_amount:0,request_type:"toil"};return e.assign({},n.defaultCustomData(),t)},toAPIFilter:function(t,n,a){e.includes(["balance_change","dates","comments","files"],a)||(t[a]=this[a])}})}])}),define("leave-absences/shared/controllers/request.controller",["common/angular","leave-absences/shared/modules/controllers","common/lodash","common/moment","common/models/contact","common/models/session.model","common/services/api/option-group","common/services/hr-settings","common/services/pub-sub","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/instances/leave-request.instance","leave-absences/shared/instances/sickness-request.instance","leave-absences/shared/instances/toil-request.instance","leave-absences/shared/services/leave-request.service"],function(e,t,n,a){"use strict";function r(t,r,o,s,i,u,c,l,d,m,f,p,h,v,g,b,y,_,q,$,w){function C(e){"days"===Le.selectedAbsenceType.calculation_unit_name?delete Le.request[e+"_date_amount"]:delete Le.request[e+"_date_type"]}function A(){["from","to"].forEach(C)}function P(){var e=Le.requestStatuses[_.statusNames.awaitingApproval].value;Se.status_id===e&&e!==Le.request.status_id&&d.publish("ManagerBadge:: Update Count")}function D(){return Ee.filter(function(e){return e.isRequired}).every(function(e){return e.canSubmit&&e.canSubmit()})}function T(){return Ee.filter(function(e){return!e.isRequired}).some(function(e){return e.canSubmit&&e.canSubmit()})}function S(){return!Le.loading.entitlements&&(!!oe("admin")||!ae("view")&&!(oe("manager")&&!ae("create")))}function R(){var e=D();return Le.isMode("edit")&&(e=e&&(V()||T())),Le.canManage&&Le.requestStatuses&&(e=e&&!!Le.getStatusFromValue(Le.newStatusOnSave)),(e=e&&!!Le.period.id)&&!Le.isMode("view")}function O(){Le.isSelfRecord?Le.request.status_id=Le.requestStatuses[_.statusNames.awaitingApproval].value:Le.canManage&&(Le.request.status_id=Le.newStatusOnSave||Le.request.status_id)}function I(){if(Le.isMode("edit")&&!Le.isRole("staff")&&"toil"!==F())return Le.request.calculateBalanceChange(Le.selectedAbsenceType.calculation_unit_name).then(function(e){if(+Le.balance.change.amount!=+e.amount)return w.promptBalanceChangeRecalculation().then(function(){o.$emit("LeaveRequestPopup::recalculateBalanceChange")}),r.reject()})}function x(){Le.errors=[]}function E(){return Le.request.create().then($e).then(function(){fe("LeaveRequest::new")})}function L(){ee()&&!Le.isRole("staff")&&(Le.request.change_balance=!0)}function M(){l.open({title:"Confirm Deletion?",copyCancel:"Cancel",copyConfirm:"Confirm",classConfirm:"btn-danger",msg:"This cannot be undone",onConfirm:function(){return Le.request.delete().then(function(){Le.dismissModal(),d.publish("LeaveRequest::delete",Le.request)})}})}function k(){i.dismiss({$value:"cancel"})}function j(){var e=F();return"leave"===e?{is_sick:!1}:"sickness"===e?{is_sick:!0}:"toil"===e?{allow_accruals_request:!0}:void 0}function B(){return N(Le.getStatusFromValue(Le.request.status_id).name)}function N(e){return n.map(De[e],function(e){return Le.requestStatuses[e]})}function F(){return Le.request?Le.request.request_type:Le.leaveType||null}function U(){return!Le.request||e.equals({},Le.requestStatuses)?[]:Le.request.status_id?B():N("none")}function H(e){return n.find(Le.requestStatuses,function(t){return t.value===e})}function W(e){Le.errors=n.isArray(e)?e:[e],Le.loading.absenceTypes=!1,Le.submitting=!1}function V(){return!e.equals(Se,Le.request.attributes())||Le.canManage&&Le.newStatusOnSave}function G(){return Le.postContactSelection=!0,Le.staffMemberSelectionComplete=!1,Le.request.contact_id?r.resolve().then(ie).then(ue).then(he).then(ge).then(Z).then(z).then(Le.isMode("edit")?be:n.noop).then(function(){Le.postContactSelection=!1,Le.staffMemberSelectionComplete=!0}).catch(function(e){if(e!==Ie)return r.reject(e)}):r.reject("The contact id was not set")}function Y(){var e=[_.statusNames.moreInformationRequired,_.statusNames.approved,_.statusNames.rejected,_.statusNames.cancelled];De.none=[_.statusNames.moreInformationRequired,_.statusNames.approved],De.awaiting_approval=e,De.more_information_required=e,De.rejected=e,De.approved=e,De.cancelled=[_.statusNames.awaitingApproval].concat(e)}function z(){return Le.canManage?f.find(Le.request.contact_id).then(function(e){Le.contactName=e.display_name}):r.resolve()}function X(){Re.push(o.$on("LeaveRequestPopup::requestObjectUpdated",be),o.$on("LeaveRequestPopup::absencePeriodChanged",function(){ue().then(he).then(function(){o.$emit("LeaveRequestPopup::absencePeriodBalancesUpdated",Le.absenceTypes)})}),o.$on("LeaveRequestPopup::handleError",function(e,t){W(t)}),o.$on("LeaveRequestPopup::childComponent::register",function(){Te++})),s.$on("$destroy",we),s.$on("LeaveRequestPopup::addTab",function(e,t){Ee.push(t)})}function J(){var e,t;Le.request=Le.leaveRequest||null,e=F(),t=Le.initRequestAttributes(),"leave"===e?Le.request=y.init(t):"sickness"===e?Le.request=q.init(t):"toil"===e&&(Le.request=$.init(t))}function K(){var e={};return Le.request?e=Le.request.attributes():Le.canManage||(e={contact_id:Oe}),e}function Q(){if(xe="staff","my-leave"!==o.section)return u(_.permissions.admin.administer).then(function(e){e&&(xe="admin")}).then(function(){return"staff"===xe&&u(_.permissions.ssp.manage).then(function(e){e&&(xe="manager")})}).finally(function(){Le.canManage=Le.isRole("manager")||Le.isRole("admin")})}function Z(){(Le.isRole("admin")||Le.isMode("create")&&Le.isRole("manager"))&&(Le.newStatusOnSave=Le.requestStatuses[_.statusNames.approved].value)}function ee(){return!Le.request.status_id||!n.includes(["cancelled","rejected"],H(Le.request.status_id).name)}function te(e){var t=Le.getStatusFromValue(Le.request.status_id);return!!t&&t.name===e}function ne(e){return Le.request&&Le.request.request_type===e}function ae(e){return Le.mode===e}function re(e,t){var n=a(e.from_date),r=a(e.to_date);return n.isSameOrAfter(t.start_date,"day")&&r.isSameOrBefore(t.end_date,"day")}function oe(e){return xe===e}function se(){return h.all().then(function(e){Le.absencePeriods=e})}function ie(){return v.all(j()).then(v.loadCalculationUnits).then(function(e){Pe={types:e,ids:e.map(function(e){return e.id})}})}function ue(){return Le.loading.entitlements=!0,g.all({contact_id:Le.request.contact_id,period_id:Le.period.id,type_id:{IN:Pe.ids}},!0).finally(function(){Le.loading.entitlements=!1})}function ce(){return p.get().then(function(e){Oe=e.contactId})}function le(){return Le.selectedContactId?f.find(Le.selectedContactId).then(function(e){Le.managedContacts=[e]}):Le.isRole("admin")?f.all().then(function(e){Le.managedContacts=n.remove(e.list,function(e){return e.id!==Oe})}):f.find(Oe).then(function(e){return e.leaveManagees()}).then(function(e){Le.managedContacts=e})}function de(){return c.valuesOf("hrleaveandabsences_leave_request_status").then(function(e){Le.requestStatuses=n.indexBy(e,"name")})}function me(e,t){var a;return n.compact(e.map(function(e){if(a=n.find(t,{type_id:e.id}))return{id:a.type_id,title:e.title+" ( "+a.remainder.current+" ) ",remainder:a.remainder.current,allow_overuse:e.allow_overuse,calculation_unit_name:e.calculation_unit_name}}))}function fe(e){P(),d.publish(e,Le.request),Le.errors=[],Le.dismissModal()}function pe(){["from","to"].forEach(function(e){Le.request[e+"_date"]=Se[e+"_date"]})}function he(e){if(Le.absenceTypes=me(Pe.types,e),!Le.absenceTypes.length)return r.reject(Ie)}function ve(){Le.period=n.find(Le.absencePeriods,function(e){return Le.isMode("create")?e.current:re(Le.request,e)})}function ge(){Le.isMode("create")?(Le.selectedAbsenceType=Le.absenceTypes[0],Le.request.type_id=Le.selectedAbsenceType.id):Le.selectedAbsenceType=n.find(Le.absenceTypes,function(e){return e.id===Le.request.type_id})}function be(){Se=e.copy(Le.request.attributes())}function ye(){var e;Le.request.id?(e=[Le.requestStatuses[_.statusNames.approved].value,Le.requestStatuses[_.statusNames.adminApproved].value,Le.requestStatuses[_.statusNames.rejected].value,Le.requestStatuses[_.statusNames.cancelled].value],Le.mode="edit",Le.isRole("staff")&&e.indexOf(Le.request.status_id)>-1&&(Le.mode="view")):Le.mode="create"}function _e(){var e=Le.request.status_id;if(!Le.isMode("view")&&!Le.submitting)return Le.submitting=!0,O(),A(),Le.request.isValid().then(ee()&&I).then(L).then(!Le.request.change_balance&&pe).then(qe).then(function(){return Le.isMode("edit")?Ae():E()}).catch(function(t){Le.request.status_id=e,t&&W(t)}).finally(function(){Le.submitting=!1})}function qe(){return r.all(Ee.map(function(e){return e.onBeforeSubmit&&e.onBeforeSubmit()}))}function $e(){function e(e){e&&n.push(e),++a===Te&&(n.length>0?t.reject(n):t.resolve())}var t=r.defer(),n=[],a=0;return Te>0?o.$broadcast("LeaveRequestPopup::submit",e):t.resolve(),t.promise}function we(){Re.forEach(function(e){e()})}function Ce(){o.$broadcast("LeaveRequestPopup::absenceTypeChanged")}function Ae(){return Le.request.update().then($e).then(function(){Le.isRole("manager")?fe("LeaveRequest::updatedByManager"):(Le.isRole("staff")||Le.isRole("admin"))&&fe("LeaveRequest::edit")})}t.debug("RequestCtrl");var Pe,De={},Te=0,Se={},Re=[],Oe="",Ie="No entitlement",xe="",Ee=[],Le=n.assign(this,m);Le.absencePeriods=[],Le.absenceTypes=[],Le.canManage=!1,Le.contactName=null,Le.errors=[],Le.loading={absenceTypes:!0,entitlements:!0},Le.managedContacts=[],Le.mode="",Le.newStatusOnSave=null,Le.period={},Le.postContactSelection=!1,Le.requestStatuses={},Le.selectedAbsenceType={},Le.staffMemberSelectionComplete=!1,Le.submitting=!1,Le.balance={closing:0,opening:0,change:{amount:0,breakdown:[]}},Le.canChangeAbsenceType=S,Le.canSubmit=R,Le.closeAlert=x,Le.deleteLeaveRequest=M,Le.dismissModal=k,Le.getStatuses=U,Le.getStatusFromValue=H,Le.initAfterContactSelection=G,Le.initRequestAttributes=K,Le.isLeaveStatus=te,Le.isLeaveType=ne,Le.isMode=ae,Le.isRole=oe,Le.submit=_e,Le.updateAbsenceType=Ce,function(){Le.loading.absenceTypes=!0,Y(),X(),r.all([ce(),Q(),se(),de()]).then(J).then(ye).then(ve).then(function(){return Le.canManage&&!Le.isMode("edit")&&le()}).then(function(){if(Le.selectedContactId&&(Le.request.contact_id=Le.selectedContactId),Le.request.contact_id)return Le.initAfterContactSelection()}).catch(W).finally(function(){Le.loading.absenceTypes=!1})}()}t.controller("RequestCtrl",r),r.$inject=["$log","$q","$rootScope","$scope","$uibModalInstance","checkPermissions","api.optionGroup","dialog","pubSub","directiveOptions","Contact","Session","AbsencePeriod","AbsenceType","Entitlement","LeaveRequest","LeaveRequestInstance","shared-settings","SicknessRequestInstance","TOILRequestInstance","LeaveRequestService"]}),define("leave-absences/shared/services/leave-popup.service",["common/lodash","common/modules/angular-date","leave-absences/shared/modules/services","common/services/angular-date/date-format","common/services/notification.service","leave-absences/shared/controllers/request.controller"],function(e,t){"use strict";function n(e,t,n,a,r,o,s,i,u){function c(e){return i.get().then(function(t){return e.roleOf(t.contactId)}).then(function(e){return"none"!==e})}function l(e,n,r,s,i){a.open({appendTo:t.children().eq(0),templateUrl:o.sharedPathTpl+"components/leave-request-popup/leave-request-popup.html",controller:"RequestCtrl",controllerAs:"$ctrl",windowClass:"chr_leave-request-modal",resolve:{directiveOptions:function(){return{leaveType:n,leaveRequest:e,selectedContactId:r,isSelfRecord:s,forceRecalculateBalanceChange:i}},format:["DateFormat",function(e){return e.getDateFormat()}]}})}function d(e){return u.find(e).then(function(e){return c(e).then(function(t){t?l(e,e.request_type,e.contact_id,"my-leave"===n.section):r.error("Error","You dont have permission to see this leave request")})}).catch(function(e){r.error("Error",e)})}return e.debug("LeavePopup"),{openModal:l,openModalByID:d}}t.factory("LeavePopup",n),n.$inject=["$log","$rootElement","$rootScope","$uibModal","notificationService","shared-settings","DateFormat","Session","LeaveRequest"]}),define("leave-absences/my-leave/modules/components",["common/angular"],function(e){return e.module("my-leave.components",[])}),define("leave-absences/my-leave/components/my-leave-container.component",["leave-absences/my-leave/modules/components"],function(e){e.component("myLeaveContainer",{bindings:{contactId:"<"},templateUrl:["settings",function(e){return e.pathTpl+"components/my-leave-container.html"}],controllerAs:"myleave",controller:["$log","$rootScope","$state",function(e,t,n){function a(){n.go(r.tabName)}e.debug("Component: my-leave-container"),t.section="my-leave";var r=this;r.tabName=n.current.name,r.changeTab=a}]})}),function(e){define("leave-absences/my-leave/modules/settings",["common/angular"],function(t){return t.module("my-leave.settings",[]).constant("settings",{debug:e.debug,pathTpl:e.vars.leaveAndAbsences.baseURL+"/views/my-leave/"})})}(CRM),function(e){define("leave-absences/my-leave/modules/config",["common/angular","leave-absences/my-leave/modules/settings"],function(t){return t.module("my-leave.config",["my-leave.settings"]).config(["$stateProvider","$resourceProvider","$urlRouterProvider","$httpProvider","$logProvider","settings",function(t,n,a,r,o,s){o.debugEnabled(s.debug),n.defaults.stripTrailingSlashes=!1,r.defaults.headers.common["X-Requested-With"]="XMLHttpRequest",a.otherwise("/my-leave/report"),t.state("my-leave",{abstract:!0,url:"/my-leave",template:'',resolve:{contactId:function(){return e.vars.leaveAndAbsences.contactId},format:["DateFormat",function(e){return e.getDateFormat()}]}}).state("my-leave.report",{url:"/report?leave-request-id",template:'',onEnter:["$stateParams","LeavePopup",function(e,t){e["leave-request-id"]&&t.openModalByID(e["leave-request-id"])}]}).state("my-leave.calendar",{url:"/calendar",template:''})}])})}(CRM), +define("leave-absences/my-leave/app",["common/angular","common/angularBootstrap","common/text-angular","common/directives/loading","common/directives/scroll-shadows.directive","common/directives/time-amount-picker.directive","common/directives/timepicker-select.directive","common/filters/angular-date/format-date","common/filters/time-unit-applier.filter","common/models/option-group","common/modules/dialog","common/services/check-permissions","common/services/crm-ang.service","common/services/angular-date/date-format","leave-absences/shared/ui-router","leave-absences/shared/modules/shared-settings","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/components/leave-calendar.component","leave-absences/shared/components/leave-calendar-day.component","leave-absences/shared/components/leave-calendar-legend.component","leave-absences/shared/components/leave-calendar-month.component","leave-absences/shared/components/leave-request-actions.component","leave-absences/shared/components/leave-request-popup-comments-tab.component","leave-absences/shared/components/leave-request-popup-details-tab.component","leave-absences/shared/components/leave-request-popup-files-tab","leave-absences/shared/components/leave-request-record-actions.component","leave-absences/shared/components/staff-leave-report.component","leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller","leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller","leave-absences/shared/models/absence-period.model","leave-absences/shared/models/absence-type.model","leave-absences/shared/models/calendar.model","leave-absences/shared/models/entitlement.model","leave-absences/shared/models/leave-request.model","leave-absences/shared/models/public-holiday.model","leave-absences/shared/modules/shared-settings","leave-absences/shared/modules/shared-settings","leave-absences/shared/services/leave-popup.service","leave-absences/my-leave/components/my-leave-container.component","leave-absences/my-leave/modules/config"],function(e){return e.module("my-leave",["ngResource","ngAnimate","ui.bootstrap","ui.router","textAngular","common.angularDate","common.dialog","common.directives","common.filters","common.mocks","common.models","common.services","leave-absences.components","leave-absences.controllers","leave-absences.models","leave-absences.services","leave-absences.settings","my-leave.components","my-leave.config"]).run(["$log","$rootScope","shared-settings","settings",function(e,t,n,a){e.debug("app.run"),t.sharedPathTpl=n.sharedPathTpl,t.settings=a}]),e}),function(e,t){var n=e.vars.leaveAndAbsences.baseURL+"/js/angular/src/leave-absences";t.config({urlArgs:"bust="+(new Date).getTime(),paths:{"leave-absences/shared":n+"/shared","leave-absences/my-leave":n+"/my-leave"}}),t(["leave-absences/shared/config"],function(){t(["leave-absences/my-leave/app"],function(e){e.bootstrap(document.querySelector("[data-leave-absences-my-leave]"),["my-leave"])})})}(CRM,require),define("my-leave",function(){}); //# sourceMappingURL=/sites/all/modules/civicrm/tools/extensions/civihr/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/dist/my-leave.js.map \ No newline at end of file diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/app.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/app.js index 0a1c4ce346d..40ec97e1787 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/app.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/app.js @@ -12,6 +12,7 @@ define([ 'common/modules/dialog', 'common/modules/directives', 'common/services/check-permissions', + 'common/services/crm-ang.service', 'common/services/angular-date/date-format', 'common/services/notification.service', 'leave-absences/shared/modules/shared-settings', diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component.js index bb35ad96785..3a6d1439a7a 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-custom-work-pattern-modal.component.js @@ -13,10 +13,10 @@ define([ return settings.pathTpl + 'components/absence-tab-custom-work-pattern-modal.html'; }], controllerAs: 'workPatternModal', - controller: ['$log', '$q', '$rootScope', 'OptionGroup', 'shared-settings', 'WorkPatternAPI', controller] + controller: ['$log', '$q', '$rootScope', 'crmAngService', 'OptionGroup', 'shared-settings', 'WorkPatternAPI', controller] }); - function controller ($log, $q, $rootScope, OptionGroup, sharedSettings, WorkPatternAPI) { + function controller ($log, $q, $rootScope, crmAngService, OptionGroup, sharedSettings, WorkPatternAPI) { $log.debug('Component: absence-tab-custom-work-pattern-modal'); var vm = Object.create(this); @@ -40,15 +40,16 @@ define([ } } }; + vm.openWorkPatternChangeReasonEditor = openWorkPatternChangeReasonEditor; (function init () { return $q.all([ loadWorkPatterns(), - loadJobContractRevisionChangeReasons() + loadJobContractRevisionChangeReasons(true) ]) - .finally(function () { - vm.loading.content = false; - }); + .finally(function () { + vm.loading.content = false; + }); })(); /** @@ -107,17 +108,28 @@ define([ } /** - * Loads the Job Contract Revision Change Reasons and indexes by `value` + * Loads the Leave and Absences Work Pattern Change Reasons * - * @return {Promise} + * @param {Boolean} cache if to cache results of the API call, cache by default + * @return {Promise} resolves with {Array} */ - function loadJobContractRevisionChangeReasons () { - return OptionGroup.valuesOf('hrjc_revision_change_reason') + function loadJobContractRevisionChangeReasons (cache) { + return OptionGroup.valuesOf('hrleaveandabsences_work_pattern_change_reason', cache) .then(function (reasons) { vm.changeReasons = reasons; }); } + /** + * Opens the work pattern change reasons for editing + */ + function openWorkPatternChangeReasonEditor () { + crmAngService.loadForm('/civicrm/admin/options/hrleaveandabsences_work_pattern_change_reason?reset=1') + .on('crmUnload', function () { + loadJobContractRevisionChangeReasons(false); + }); + } + return vm; } }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-work-patterns.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-work-patterns.component.js index dfdb479e816..8d20a053a16 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-work-patterns.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/absence-tab/components/absence-tab-work-patterns.component.js @@ -104,12 +104,12 @@ define([ } /** - * Loads the Job Contract Revision Change Reasons and indexes by `value` + * Loads the Leave and Absences Work Pattern Change Reasons * - * @return {Promise} + * @return {Promise} resolves with {Array} */ function loadJobContractRevisionChangeReasons () { - return OptionGroup.valuesOf('hrjc_revision_change_reason') + return OptionGroup.valuesOf('hrleaveandabsences_work_pattern_change_reason') .then(function (reasons) { changeReasons = _.indexBy(reasons, 'value'); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/admin-dashboard/app.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/admin-dashboard/app.js index 581410a7ed0..e496863348b 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/admin-dashboard/app.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/admin-dashboard/app.js @@ -10,6 +10,7 @@ define([ 'common/filters/time-unit-applier.filter', 'common/modules/dialog', 'common/services/check-permissions', + 'common/services/crm-ang.service', 'common/services/angular-date/date-format', 'leave-absences/shared/ui-router', 'leave-absences/shared/components/leave-balance-tab.component', diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/manager-leave/app.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/manager-leave/app.js index b591216b9c0..ac140d1f4cb 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/manager-leave/app.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/manager-leave/app.js @@ -13,6 +13,7 @@ define([ 'common/modules/dialog', 'common/services/angular-date/date-format', 'common/services/check-permissions', + 'common/services/crm-ang.service', 'leave-absences/shared/ui-router', 'leave-absences/shared/models/absence-period.model', 'leave-absences/shared/models/absence-type.model', diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/my-leave/app.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/my-leave/app.js index a163035cfbd..a5adeb64718 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/my-leave/app.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/my-leave/app.js @@ -13,6 +13,7 @@ define([ 'common/models/option-group', 'common/modules/dialog', 'common/services/check-permissions', + 'common/services/crm-ang.service', 'common/services/angular-date/date-format', 'leave-absences/shared/ui-router', 'leave-absences/shared/modules/shared-settings', diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-day.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-day.component.js index 1c1224c035c..837fe05646a 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-day.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-day.component.js @@ -18,194 +18,213 @@ define([ controller: LeaveCalendarDayController }); - LeaveCalendarDayController.$inject = ['$log', '$scope', 'LeavePopup']; + LeaveCalendarDayController.$inject = ['$log', '$scope', '$timeout', 'LeavePopup']; - function LeaveCalendarDayController ($log, $scope, LeavePopup) { + function LeaveCalendarDayController ($log, $scope, $timeout, LeavePopup) { 'use strict'; $log.debug('Component: leave-calendar-day'); - var absenceType, fromDateType, toDateType; var vm = this; - vm.calculationUnit = ''; - vm.dates = { from: null, to: null }; - vm.label = ''; - vm.tooltipTemplate = null; + vm.tooltip = { + show: false, + day_cell_hovered: false, + tooltip_hovered: false + }; vm.openLeavePopup = openLeavePopup; + vm.toggleTooltip = toggleTooltip; (function init () { - watchForLeaveRequestReady(); + watchLeaveRequests(); })(); /** - * Finds and stores the calculation unit for the leave request's - * absence type + * Opens the leave request popup + * + * When leave-request-actions.component sits inside manage-request component's table rows, + * and the table row has a click event to open leave request, so event.stopPropagation() + * is necessary to prevent the parents click event from being called + * + * @param {Object} event + * @param {Object} leaveRequest + * @param {String} leaveType + * @param {String} selectedContactId + * @param {Boolean} isSelfRecord */ - function findAbsenceTypeCalculationUnit () { - vm.calculationUnit = findRecordByIdFieldValue( - vm.supportData.calculationUnits, 'value', absenceType.calculation_unit); + function openLeavePopup (event, leaveRequest, leaveType, selectedContactId, isSelfRecord) { + event.stopPropagation(); + LeavePopup.openModal(leaveRequest, leaveType, selectedContactId, isSelfRecord); } /** - * Given an array of records, finds and returns the one that matches the - * id field with the comparison value. + * Determines the label for the day when calculation units are set to days. * - * @param {Array} records - An array of objects to filter. - * @param {String} idFieldName - the name for the ID field. - * @param {any} value - The comparison value to match against the ID. + * AM: leave requests for half day AM + * PM: leave requests for half day PM + * Otherwise leave empty. * - * @return {Object} + * @param {Object} leaveRequestAttributes + * @return {String} */ - function findRecordByIdFieldValue (records, idFieldName, value) { - return _.find(records, function (record) { - return +record[idFieldName] === +value; - }); + function resolveDayLabelForDaysCalculationUnit (leaveRequestAttributes) { + return leaveRequestAttributes.isAM + ? 'AM' + : leaveRequestAttributes.isPM + ? 'PM' + : ''; } /** - * Returns the template name for Leave Requests tooltips. + * Determines the label for the day when calculation units are set to hours. * - * The pattern is `type-[days|hours]-on-[single-date|multiple-dates]-tooltip` + * If the date is the same as the start date of the request, the start time + * is displayed. + * If the date is the same as the end date of the request, the end time is + * displayed. + * Otherwise the label is empty. * + * @param {LeaveRequestInstance} leaveRequest * @return {String} */ - function getTooltipTemplateForLeaveRequests () { - var dateRangeType, isSameDay; - - isSameDay = moment(vm.contactData.leaveRequest.from_date) - .isSame(vm.contactData.leaveRequest.to_date, 'day'); - dateRangeType = isSameDay ? 'single-date' : 'multiple-dates'; + function resolveDayLabelForHoursCalculationUnit (leaveRequest) { + var sameDateAsFromDate = moment(leaveRequest.from_date) + .isSame(vm.date, 'day'); + var sameDateAsToDate = moment(leaveRequest.to_date) + .isSame(vm.date, 'day'); - return 'type-' + vm.calculationUnit.name + '-on-' + - dateRangeType + '-tooltip'; + return sameDateAsFromDate + ? moment(leaveRequest.from_date).format('HH:mm') + : sameDateAsToDate + ? moment(leaveRequest.to_date).format('HH:mm') + : ''; } /** - * Maps the absence type title to the leave request. + * Sets absence types titles to leave requests attributes + * + * @param {LeaveRequestInstance} leaveRequest + * @param {Object} leaveRequestAttributes */ - function mapLeaveRequestAbsenceType () { - absenceType = findRecordByIdFieldValue(vm.supportData.absenceTypes, - 'id', vm.contactData.leaveRequest.type_id); - - vm.contactData.leaveRequest['type_id.title'] = absenceType.title; + function resolveLeaveRequestAbsenceTypeTitle (leaveRequest, leaveRequestAttributes) { + vm.contactData.leaveRequestsAttributes[leaveRequest.id].absenceTypeTitle = + _.find(vm.supportData.absenceTypes, { id: leaveRequest.type_id }).title; } /** - * Maps the from and to date type labels to the leave request. + * Sets a unit name to the leave requests attributes + * + * @param {LeaveRequestInstance} leaveRequest + * @param {Object} leaveRequestAttributes */ - function mapLeaveRequestDateTypes () { - if (vm.calculationUnit.name === 'days') { - fromDateType = findRecordByIdFieldValue(vm.supportData.dayTypes, - 'value', vm.contactData.leaveRequest.from_date_type); - toDateType = findRecordByIdFieldValue(vm.supportData.dayTypes, - 'value', vm.contactData.leaveRequest.to_date_type); - - vm.contactData.leaveRequest['from_date_type.label'] = fromDateType.label; - vm.contactData.leaveRequest['to_date_type.label'] = toDateType.label; - } + function resolveLeaveRequestCalculationUnit (leaveRequest, leaveRequestAttributes) { + var absenceType = _.find(vm.supportData.absenceTypes, { id: leaveRequest.type_id }); + var calculationUnit = _.find(vm.supportData.calculationUnits, { 'value': absenceType.calculation_unit }); + + leaveRequestAttributes.unit = calculationUnit.name; } /** - * Opens the leave request popup - * - * When leave-request-actions.component sits inside manage-request component's table rows, - * and the table row has a click event to open leave request, so event.stopPropagation() - * is necessary to prevent the parents click event from being called + * Sets dates from leave requests to leave requests attributes + * by converting them from String to Date type. * - * @param {Object} event - * @param {Object} leaveRequest - * @param {String} leaveType - * @param {String} selectedContactId - * @param {Boolean} isSelfRecord + * @param {LeaveRequestInstance} leaveRequest + * @param {Object} leaveRequestAttributes */ - function openLeavePopup (event, leaveRequest, leaveType, selectedContactId, isSelfRecord) { - event.stopPropagation(); - LeavePopup.openModal(leaveRequest, leaveType, selectedContactId, isSelfRecord); + function resolveLeaveRequestDates (leaveRequest, leaveRequestAttributes) { + leaveRequestAttributes.from_date = new Date(leaveRequest.from_date); + leaveRequestAttributes.to_date = new Date(leaveRequest.to_date); } /** - * Copies dates from Leave Request, converts them from String - * to Date type and sets to the component. + * Sets the from and to date type labels to the leave requests attributes. + * + * @param {LeaveRequestInstance} leaveRequest + * @param {Object} leaveRequestAttributes */ - function resolveDayDates () { - vm.dates.from = new Date(vm.contactData.leaveRequest.from_date); - vm.dates.to = new Date(vm.contactData.leaveRequest.to_date); + function resolveLeaveRequestDateTypes (leaveRequest, leaveRequestAttributes) { + if (leaveRequestAttributes.unit !== 'days') { + return; + } + + leaveRequestAttributes['from_date_type'] = + _.find(vm.supportData.dayTypes, { value: leaveRequest.from_date_type }).label; + leaveRequestAttributes['to_date_type'] = + _.find(vm.supportData.dayTypes, { value: leaveRequest.to_date_type }).label; } /** - * Determines the label for the day depending on the calculation unit or if - * it's an accrued TOIL request. + * Determines a label for the leave request depending on the calculation unit + * or if it's an accrued TOIL request. + * + * @param {LeaveRequestInstance} leaveRequest + * @param {Object} leaveRequestAttributes */ - function resolveDayLabel () { - if (vm.contactData.isAccruedTOIL) { - vm.label = 'AT'; - } else if (vm.calculationUnit.name === 'days') { - resolveDayLabelForDaysCalculationUnit(); + function resolveLeaveRequestLabel (leaveRequest, leaveRequestAttributes) { + var label = ''; + + if (leaveRequestAttributes.isAccruedTOIL) { + label = 'AT'; + } else if (leaveRequestAttributes.unit === 'days') { + label = resolveDayLabelForDaysCalculationUnit(leaveRequestAttributes); } else { - resolveDayLabelForHoursCalculationUnit(); + label = resolveDayLabelForHoursCalculationUnit(leaveRequest); } + + leaveRequestAttributes.label = label; } /** - * Determines the label for the day when calculation units are set to days. + * Sets additional data needed for UI to leave requests attributes * - * AM: leave requests for half day AM - * PM: leave requests for half day PM - * Otherwise leave empty. + * @param {LeaveRequestInstance} leaveRequest */ - function resolveDayLabelForDaysCalculationUnit () { - vm.label = vm.contactData.isAM ? 'AM' - : vm.contactData.isPM ? 'PM' - : ''; + function resolveLeaveRequestsAdditionalUIData (leaveRequest) { + var leaveRequestAttributes = + vm.contactData.leaveRequestsAttributes[leaveRequest.id]; + var resolvingFunctions = [ + resolveLeaveRequestCalculationUnit, + resolveLeaveRequestDateTypes, + resolveLeaveRequestLabel, + resolveLeaveRequestDates, + resolveLeaveRequestAbsenceTypeTitle + ]; + + resolvingFunctions.forEach(function (resolvingFunction) { + resolvingFunction.call(this, leaveRequest, leaveRequestAttributes); + }); } /** - * Determines the label for the day when calculation units are set to hours. + * Toggles tooltip for the day. + * It reacts to entering/leaving either day cell or the tooltip itself, + * if either of the elements are hovered, it remains the tooltip open. + * It instantly shows a tooltip, but has a 100ms timeout to hide it once unhovered. * - * If the date is the same as the start date of the request, the start time - * is displayed. - * If the date is the same as the end date of the request, the end time is - * displayed. - * Otherwise the label is empty. + * @TODO this should be moved to a decorator to uib-tooltip + * + * @param {String} sourceElement day_cell|tooltip + * @param {Boolean} isHovered */ - function resolveDayLabelForHoursCalculationUnit () { - var sameDateAsFromDate = moment(vm.contactData.leaveRequest.from_date) - .isSame(vm.date, 'day'); - var sameDateAsToDate = moment(vm.contactData.leaveRequest.to_date) - .isSame(vm.date, 'day'); + function toggleTooltip (sourceElement, isHovered) { + $timeout(function () { + vm.tooltip[sourceElement + '_hovered'] = isHovered; - vm.label = sameDateAsFromDate - ? moment(vm.contactData.leaveRequest.from_date).format('HH:mm') - : sameDateAsToDate - ? moment(vm.contactData.leaveRequest.to_date).format('HH:mm') - : ''; - } - - /** - * Selects the tooltip template to use to display the leave request information. - */ - function selectTooltipTemplate () { - vm.tooltipTemplate = vm.contactData.isAccruedTOIL - ? 'accrued-toil-tooltip' - : getTooltipTemplateForLeaveRequests(); + vm.tooltip.show = + vm.tooltip.day_cell_hovered || vm.tooltip.tooltip_hovered; + }, isHovered ? 0 : 100); } /** * Waits for the leave request to be accesible before mapping the necessary * leave request fields to it. */ - function watchForLeaveRequestReady () { - $scope.$watch('day.contactData.leaveRequest', function () { - if (vm.contactData && vm.contactData.leaveRequest) { - mapLeaveRequestAbsenceType(); - findAbsenceTypeCalculationUnit(); - mapLeaveRequestDateTypes(); - resolveDayLabel(); - resolveDayDates(); - selectTooltipTemplate(); + function watchLeaveRequests () { + $scope.$watch('day.contactData.leaveRequests', function () { + if (vm.contactData && vm.contactData.leaveRequests) { + vm.contactData.leaveRequests.forEach(resolveLeaveRequestsAdditionalUIData); } - }); + }, true); } } }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-month.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-month.component.js index 3ff84ab636c..b3d0068c8e7 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-month.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-calendar-month.component.js @@ -146,36 +146,87 @@ define([ * @param {LeaveRequestInstance} leaveRequest */ function deleteLeaveRequest (leaveRequest) { - removeLeaveRequestFromIndexedList(leaveRequest); - updateLeaveRequestDaysContactData(leaveRequest); + var indexedLeaveRequest = findIndexedLeaveRequest(leaveRequest); + + if (!indexedLeaveRequest) { + return; + } + + removeLeaveRequestFromIndexedList(indexedLeaveRequest); + updateLeaveRequestDaysContactData(indexedLeaveRequest); + } + + /** + * Filters leave requests out by following rule: + * If both TOIL and Non-TOIL (Leave/Sickness) requests exist + * for the same day, remove Non-TOIL requests from the collection + * + * @param {Array} leaveRequests collection of leave requests + * @return {Array} collection of references to filtered leave requests + */ + function filterLeaveRequestsToShowInCell (leaveRequests) { + var filterTOILCondition = { 'request_type': 'toil' }; + var bothTOILAndNonTOILRequestsExist = + _.some(leaveRequests, filterTOILCondition) && + !_.every(leaveRequests, filterTOILCondition); + + return bothTOILAndNonTOILRequestsExist + ? _.filter(leaveRequests, filterTOILCondition) + : leaveRequests; + } + + /** + * Finds indexed leave request by a leave request given + * + * @param {LeaveRequestInstance} leaveRequest + * @return {LeaveRequestInstance} indexed leave request + */ + function findIndexedLeaveRequest (leaveRequest) { + var indexedLeaveRequest; + + _.find(leaveRequests[leaveRequest.contact_id], function (day) { + indexedLeaveRequest = _.find(day, function (leaveRequestObj) { + return +leaveRequestObj.id === +leaveRequest.id; + }); + + return indexedLeaveRequest; + }); + + return indexedLeaveRequest; } /** * Get profile URL for the given contact id * - * @param {string/int} contactId + * @param {String|Integer} contactId */ function getContactUrl (contactId) { return CRM.url('civicrm/contact/view', { cid: contactId }); } /** - * If there are contacts to reduce to, reduces contacts to the list provided, - * plus leaves those who have leave requests at the given month period + * Returns leave requests additional attributes for UI * - * @return {Promise} + * @param {Object} day + * @param {Array} leaveRequests [{LeaveRequestInstance}] + * @return {Object} collection of leave requests attributes + * indexed by leave requests IDs */ - function reduceContacts () { - if (vm.contactIdsToReduceTo) { - vm.contacts = vm.contacts.filter(function (contact) { - return (_.includes(vm.contactIdsToReduceTo, contact.contact_id) || - _.find(leaveRequests, function (leaveRequest) { - return leaveRequest.contact_id === contact.contact_id; - })); - }); - } + function getLeaveRequestsAttributes (day, leaveRequests) { + var attributes = {}; + + leaveRequests.forEach(function (leaveRequest) { + attributes[leaveRequest.id] = { + styles: styles(leaveRequest), + isAccruedTOIL: isLeaveType(leaveRequest, 'toil'), + isRequested: isRequested(leaveRequest), + isAM: isDayType('half_day_am', leaveRequest, day.date), + isPM: isDayType('half_day_pm', leaveRequest, day.date), + isSingleDay: moment(leaveRequest.from_date).isSame(leaveRequest.to_date, 'day') + }; + }); - return $q.resolve(); + return attributes; } /** @@ -203,7 +254,11 @@ define([ leaveRequests[leaveRequest.contact_id] = leaveRequests[leaveRequest.contact_id] || {}; days.forEach(function (day) { - leaveRequests[leaveRequest.contact_id][day.date] = leaveRequest; + if (!leaveRequests[leaveRequest.contact_id][day.date]) { + leaveRequests[leaveRequest.contact_id][day.date] = []; + } + + leaveRequests[leaveRequest.contact_id][day.date].push(leaveRequest); }); }); @@ -312,18 +367,6 @@ define([ return days; } - /** - * Finds the given leave request in the internal indexed list - * - * @param {LeaveRequestInstance} leaveRequest - * @return {LeaveRequestInstance} - */ - function leaveRequestFromIndexedList (leaveRequest) { - return _.find(leaveRequests[leaveRequest.contact_id], function (leaveRequestObj) { - return leaveRequest.id === leaveRequestObj.id; - }); - } - /** * Returns leave status value from name * @@ -366,14 +409,12 @@ define([ loadMonthWorkPatternCalendars(), loadMonthLeaveRequests() ]) - .then(reduceContacts) - .then(setMonthDaysContactData) - .then(function () { - dataLoaded = true; - }) - .then(function () { - vm.month.loading = false; - }); + .then(reduceContacts) + .then(setMonthDaysContactData) + .then(function () { + dataLoaded = true; + vm.month.loading = false; + }); } /** @@ -392,9 +433,9 @@ define([ })}, type_id: { IN: _.pluck(vm.supportData.absenceTypes, 'id') } }, null, null, null, false) - .then(function (leaveRequestsData) { - return indexLeaveRequests(leaveRequestsData.list); - }); + .then(function (leaveRequestsData) { + return indexLeaveRequests(leaveRequestsData.list); + }); } /** @@ -409,9 +450,28 @@ define([ return Calendar.get(vm.contacts.map(function (contact) { return contact.id; }), monthStartDate, monthEndDate) - .then(function (monthCalendars) { - calendars = _.indexBy(monthCalendars, 'contact_id'); - }); + .then(function (monthCalendars) { + calendars = _.indexBy(monthCalendars, 'contact_id'); + }); + } + + /** + * If there are contacts to reduce to, reduces contacts to the list provided, + * plus leaves those who have leave requests at the given month period + * + * @return {Promise} + */ + function reduceContacts () { + if (vm.contactIdsToReduceTo) { + vm.contacts = vm.contacts.filter(function (contact) { + return (_.includes(vm.contactIdsToReduceTo, contact.contact_id) || + _.find(leaveRequests, function (leaveRequest) { + return leaveRequest.contact_id === contact.contact_id; + })); + }); + } + + return $q.resolve(); } /** @@ -420,12 +480,15 @@ define([ * @param {LeaveRequestInstance} leaveRequest */ function removeLeaveRequestFromIndexedList (leaveRequest) { - leaveRequests[leaveRequest.contact_id] = _.omit( - leaveRequests[leaveRequest.contact_id], - function (leaveRequestObj) { + var days = leaveRequestDays(leaveRequest); + + leaveRequests[leaveRequest.contact_id] = leaveRequests[leaveRequest.contact_id] || {}; + + days.forEach(function (day) { + _.remove(leaveRequests[leaveRequest.contact_id][day.date], function (leaveRequestObj) { return leaveRequestObj.id === leaveRequest.id; - } - ); + }); + }); } /** @@ -460,27 +523,26 @@ define([ workPatternCalendar.isWeekend(dateObjectWithFormat(day.date)), workPatternCalendar.isNonWorkingDay(dateObjectWithFormat(day.date)) ]) - .then(function (results) { - _.assign(day.contactsData[contactId], { - isWeekend: results[0], - isNonWorkingDay: results[1], - isPublicHoliday: isPublicHoliday(day.date) + .then(function (results) { + _.assign(day.contactsData[contactId], { + isWeekend: results[0], + isNonWorkingDay: results[1], + isPublicHoliday: isPublicHoliday(day.date) + }); }); - }); return promise.then(function () { - return leaveRequests[contactId] ? leaveRequests[contactId][day.date] : null; + return leaveRequests[contactId] && leaveRequests[contactId][day.date] ? leaveRequests[contactId][day.date] : []; }) - .then(function (leaveRequest) { - _.assign(day.contactsData[contactId], { - leaveRequest: leaveRequest || null, - styles: leaveRequest ? styles(leaveRequest) : null, - isAccruedTOIL: leaveRequest ? isLeaveType(leaveRequest, 'toil') : null, - isRequested: leaveRequest ? isRequested(leaveRequest) : null, - isAM: leaveRequest ? isDayType('half_day_am', leaveRequest, day.date) : null, - isPM: leaveRequest ? isDayType('half_day_pm', leaveRequest, day.date) : null + .then(function (leaveRequests) { + leaveRequests = sortLeaveRequests(leaveRequests); + + _.assign(day.contactsData[contactId], { + leaveRequests: leaveRequests, + leaveRequestsToShowInCell: filterLeaveRequestsToShowInCell(leaveRequests), + leaveRequestsAttributes: getLeaveRequestsAttributes(day, leaveRequests) + }); }); - }); } /** @@ -517,6 +579,13 @@ define([ } } + function sortLeaveRequests (leaveRequests) { + return _.sortBy(leaveRequests, function (leaveRequest) { + return +moment(leaveRequest.from_date).format('X') + + (isDayType('half_day_pm', leaveRequest, leaveRequest.from_date) ? 1 : 0); + }); + } + /** * Returns the styles for a specific leaveRequest * which will be used in the view for each date @@ -535,19 +604,13 @@ define([ } /** - * Updates the given leave request in the calendar - * For simplicity's sake, it directly deletes it and re-adds it + * Updates the given leave request in the calendar. + * For simplicity, it directly deletes it and re-adds it. * * @param {LeaveRequestInstance} leaveRequest */ function updateLeaveRequest (leaveRequest) { - var oldLeaveRequest = leaveRequestFromIndexedList(leaveRequest); - - if (!oldLeaveRequest) { - return; - } - - deleteLeaveRequest(oldLeaveRequest); + deleteLeaveRequest(leaveRequest); if (leaveStatusesToBeDisplayed().indexOf(leaveRequest.status_id) !== -1) { addLeaveRequest(leaveRequest); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-actions.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-actions.component.js index 25d199a62c1..609dec4a0ff 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-actions.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-actions.component.js @@ -165,16 +165,11 @@ define([ return true; } - // Others but Admin can cancel if only the leave request status is - // either "Awaiting for Approval" or "More Information Required" - if (!_.includes([statusNames.awaitingApproval, statusNames.moreInformationRequired], - leaveRequestStatus)) { - return false; - } - - // Manager can cancel disregarding the allow_request_cancelation value + // Manager can cancel regardless of the allow_request_cancelation value, + // but only if the request is either in "Awaiting for Approval" or "More Information Required" if (vm.role === 'manager') { - return true; + return _.includes([statusNames.awaitingApproval, statusNames.moreInformationRequired], + leaveRequestStatus); } // If request can only be cancelled in advance of start date diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-popup-details-tab.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-popup-details-tab.component.js index 2b0b5b7bd79..1c7a38bea0c 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-popup-details-tab.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-popup-details-tab.component.js @@ -31,16 +31,15 @@ define([ DetailsTabController.$inject = ['$controller', '$log', '$rootScope', '$scope', '$q', 'HR_settings', 'shared-settings', 'Calendar', 'OptionGroup', - 'PublicHoliday', 'LeaveRequest', '$timeout']; + 'LeaveRequest', '$timeout']; function DetailsTabController ($controller, $log, $rootScope, $scope, $q, HRSettings, sharedSettings, Calendar, OptionGroup, - PublicHoliday, LeaveRequest, $timeout) { + LeaveRequest, $timeout) { $log.debug('Component: leave-request-popup-details-tab'); var originalOpeningBalance = null; var listeners = []; var vm = this; - var workDays = {}; vm.canManage = false; vm.calendar = {}; @@ -121,9 +120,15 @@ define([ vm.dateChangeHandler = dateChangeHandler; vm.dateTypeChangeHandler = dateTypeChangeHandler; vm.daysSelectionModeChangeHandler = daysSelectionModeChangeHandler; + vm.disableAndShowLoadingTimeInput = disableAndShowLoadingTimeInput; + vm.getMomentDateWithGivenTime = getMomentDateWithGivenTime; + vm.handleError = handleError; + vm.isCalculationUnit = isCalculationUnit; vm.isLeaveType = isLeaveType; vm.isNotWorkingDay = isNotWorkingDay; vm.performBalanceChangeCalculation = performBalanceChangeCalculation; + vm.setRequestDateTimesAndDateTypes = setRequestDateTimesAndDateTypes; + vm.updateEndTimeInputMinTime = updateEndTimeInputMinTime; vm.$onDestroy = unsubscribeFromEvents; (function init () { @@ -148,8 +153,9 @@ define([ .then(!vm.isMode('create') && initDates) .then(setDaysSelectionMode) .then(function () { - if (!vm.isMode('create') && isCalculationUnit('hours')) { - return initTimes() + if (!vm.isMode('create')) { + return $q.resolve() + .then(vm.initTimesExtended) .then(setRequestDateTimesAndDateTypes); } }) @@ -157,11 +163,8 @@ define([ .then(initOriginalOpeningBalance) .then(setOpeningBalance) .then(initBalanceChange) - .then(function () { - if (!vm.isMode('view') && !isLeaveType('toil')) { - initTimeAndDeductionInputsWatchers(); - } - }) + .then(initFromTimeWatcher) + .then(!vm.isMode('view') && vm.initWatchersExtended) .catch(handleError) .finally(function () { vm.loading.tab = false; @@ -207,7 +210,7 @@ define([ return $q.resolve() .then(function () { - resetUIDayTypesTimeAndDeductions(dateType); + resetUIInputs(dateType); if (dateType === 'from') { resetToDateIfGreaterThanFromDate(); @@ -223,7 +226,6 @@ define([ vm.loading[dateType + 'DayTypes'] = true; }) - .then(vm.onDateChangeExtended) .then(function () { return getAbsencePeriod(dateType); }) @@ -246,15 +248,7 @@ define([ } }) .then(function () { - return loadDayTypesForDate(vm.uiOptions[dateType + 'Date'], dateType); - }) - .then(function () { - if (isCalculationUnit('hours')) { - return loadTimeRangesFromWorkPattern(dateType) - .then(function () { - setDeductionMaximumBoundary(dateType, true); - }); - } + return vm.onDateChangeExtended && vm.onDateChangeExtended(dateType); }) .then(function () { setRequestDateTimesAndDateTypes(); @@ -265,7 +259,8 @@ define([ return performBalanceChangeCalculation(); } }) - .catch(handleError); + .catch(handleError) + .finally(finishLoadingTimesAndDateTypes); } /** @@ -289,22 +284,12 @@ define([ function daysSelectionModeChangeHandler () { vm.uiOptions.toDate = null; - resetUIDayTypesTimeAndDeductions('to'); + resetUIInputs('to'); return $q.resolve() - .then(function () { - if (isCalculationUnit('hours') && vm.uiOptions.fromDate) { - disableAndShowLoadingTimeInput('from'); - (!vm.uiOptions.multipleDays) && disableAndShowLoadingTimeInput('to'); - - return loadTimeRangesFromWorkPattern('from') - .then(function () { - setDeductionMaximumBoundary('from', true); - }) - .then(setRequestDateTimesAndDateTypes); - } - }) + .then(setRequestDateTimesAndDateTypes) .then(vm.setDaysSelectionModeExtended) + .then(finishLoadingTimesAndDateTypes) .then(!vm.uiOptions.multipleDays && performBalanceChangeCalculation); } @@ -318,80 +303,19 @@ define([ var timeObject = vm.uiOptions.times[type]; timeObject.loading = true; - timeObject.disabled = true; } /** - * Enables a time input of the specified type - * and sets provided data such as minumum and maximum time values and time - * - * @param {String} type from|to + * Hides loading indicators for times and date types inputs */ - function enableAndSetDataToTimeInput (type, data) { - var timeObject = vm.uiOptions.times[type]; - var timeMin = _.clone(data.time_from); - var timeMax = _.clone(data.time_to); - - if (!vm.uiOptions.multipleDays) { - if (type === 'from' && timeMax && timeMin) { - timeMax = getMomentDateWithGivenTime(timeMax) - .subtract(vm.uiOptions.time_interval, 'minutes') - .format('HH:mm'); - } - if (type === 'to' && timeMin && timeMax) { - timeMin = getMomentDateWithGivenTime(timeMin) - .add(vm.uiOptions.time_interval, 'minutes') - .format('HH:mm'); - } - } - - timeObject.min = timeMin || '00:00'; - timeObject.max = timeMax || '00:00'; - timeObject.time = type === 'to' ? timeObject.max : timeObject.min; - timeObject.disabled = false; - } - - /** - * This method will be used on the view to return a list of available - * leave request day types (All day, Half-day AM, Half-day PM, Non working day, - * Weekend, Public holiday) for the given date (which is the date - * selected by the user via datepicker) - * - * If no date is passed, then no list is returned - * - * @param {Date} date - * @param {String} dayType - set to from if from date is selected else to - * @return {Promise} of array with day types - */ - function filterLeaveRequestDayTypes (date, dayType) { - if (!date) { - return $q.reject([]); - } - - date = convertDateToServerFormat(date); - - return PublicHoliday.isPublicHoliday(date) - .then(function (result) { - if (result) { - return vm.requestDayTypes.filter(function (publicHoliday) { - return publicHoliday.name === 'public_holiday'; - }); - } - - return getDayTypesFromDate(date, vm.requestDayTypes) - .then(function (inCalendarList) { - return inCalendarList.length - ? inCalendarList - : vm.requestDayTypes.filter(function (dayType) { - return _.includes(['all_day', 'half_day_am', 'half_day_pm'], dayType.name); - }); - }); - }) - .then(function (dayTypes) { - setDayTypes(dayType, dayTypes); + function finishLoadingTimesAndDateTypes () { + ['from', 'to'].forEach(function (dateType) { + vm.loading[dateType + 'DayTypes'] = false; - return dayTypes; - }); + if (isCalculationUnit('hours')) { + vm.uiOptions.times[dateType].loading = false; + } + }); } /** @@ -409,28 +333,6 @@ define([ }) || {}; } - /** - * Gets list of day types if its found to be weekend or non working in calendar - * - * @param {Date} date to Checks - * @param {Array} listOfDayTypes array of day types - * @return {Array} non-empty if found else empty array - */ - function getDayTypesFromDate (date, listOfDayTypes) { - date = moment(date); - - return $q.all([ - vm.calendar.isNonWorkingDay(date), - vm.calendar.isWeekend(date) - ]).then(function (results) { - return results[0] ? 'non_working_day' : (results[1] ? 'weekend' : null); - }).then(function (nameFilter) { - return !nameFilter ? [] : listOfDayTypes.filter(function (day) { - return day.name === nameFilter; - }); - }); - } - /** * Gets leave type. * @@ -470,18 +372,6 @@ define([ .catch(handleError); } - /** - * Calculates time difference in hours - * - * @param {String} timeFrom in HH:mm format - * @param {String} timeTo in HH:mm format - * @return {Number} amount of hours, eg. 7.5 - */ - function getTimeDifferenceInHours (timeFrom, timeTo) { - return moment.duration(timeTo) - .subtract(moment.duration(timeFrom)).asHours(); - } - /** * Handles errors * @@ -515,33 +405,12 @@ define([ var attributes = vm.request.attributes(); vm.uiOptions.fromDate = convertDateFormatFromServer(vm.request.from_date); + // to_date and type has been reset in above call so reinitialize from clone + vm.request.to_date = attributes.to_date; + vm.request.to_date_type = attributes.to_date_type; + vm.uiOptions.toDate = convertDateFormatFromServer(vm.request.to_date); - return loadDayTypesForDate(vm.uiOptions.fromDate, 'from') - .then(function () { - // to_date and type has been reset in above call so reinitialize from clone - vm.request.to_date = attributes.to_date; - vm.request.to_date_type = attributes.to_date_type; - vm.uiOptions.toDate = convertDateFormatFromServer(vm.request.to_date); - - return loadDayTypesForDate(vm.uiOptions.toDate, 'to'); - }); - } - - /** - * Initialises a watcher for a custom deduction input of a specified date type - * - * @param {String} dateType from|to - */ - function initDeductionInputWatcher (dateType) { - $scope.$watch('detailsTab.uiOptions.times.' + dateType + '.amount', function (amount, oldAmount) { - if (isCalculationUnit('days') || +amount === +oldAmount) { - return; - } - - setRequestHoursDeductions(); - // @NOTE `vm.` is needed for testing purposes - vm.performBalanceChangeCalculation(); - }); + return vm.initDayTypesExtended ? vm.initDayTypesExtended() : $q.resolve(); } /** @@ -582,85 +451,24 @@ define([ } /** - * Initialises time for a given date type. - * In general cases simply extracts the time from the date string and - * sets the time to the correspondent times property. - * If the time is outside the allowed range (for example after work parrern change), - * then it sets the minimum allowed time for "from" time - * and the maximum allowed time for "to" time. - * - * @param {String} dateType from|to - */ - function initTime (dateType) { - var time = moment(vm.request[dateType + '_date']).format('HH:mm'); - var timeObject = vm.uiOptions.times[dateType]; - var isOutsideWorkPatternRange = - getTimeDifferenceInHours(timeObject.min, time) <= 0 || - getTimeDifferenceInHours(timeObject.max, time) >= 0; - - if (isOutsideWorkPatternRange) { - time = dateType === 'from' ? timeObject.min : timeObject.max; - } - - vm.uiOptions.times[dateType].time = time; - } - - /** - * Initialises and sets the "from" and "to" times - * - * @return {Promise} + * Initialises watcher for from time values. + * The value of the from time input affects the min value of the to time input */ - function initTimes () { - var dateTypes = vm.uiOptions.multipleDays ? ['from', 'to'] : ['from']; - var times = vm.uiOptions.times; - - return $q.all(dateTypes.map(loadTimeRangesFromWorkPattern)) - .then(function () { - ['from', 'to'].forEach(function (dateType) { - initTime(dateType); - - setDeductionMaximumBoundary(dateType); - - times[dateType].amount = - Math.min(vm.request[dateType + '_date_amount'], times[dateType].maxAmount).toString(); - }); + function initFromTimeWatcher () { + $rootScope.$watch( + function () { + return vm.uiOptions.times.from.time; + }, + function (newValue, oldValue) { + if (newValue === oldValue) { + return; + } if (!vm.uiOptions.multipleDays) { - updateEndTimeInputMinTime(vm.uiOptions.times.from.time); + updateEndTimeInputMinTime(newValue); + setRequestDateTimesAndDateTypes(); } - }).then(setRequestHoursDeductions); - } - - /** - * Initialises watchers for time and deductions inputs - */ - function initTimeAndDeductionInputsWatchers () { - ['from', 'to'].forEach(function (dateType) { - initDeductionInputWatcher(dateType); - initTimeInputWatcher(dateType); - }); - } - - /** - * Initialises a watcher for a time input of a specified date type - * - * @param {String} dateType from|to - */ - function initTimeInputWatcher (dateType) { - $scope.$watch('detailsTab.uiOptions.times.' + dateType + '.time', function (time, oldTime) { - if (isCalculationUnit('days') || time === oldTime) { - return; - } - - setRequestDateTimesAndDateTypes(); - - if (!time) { - return; - } - - (!vm.uiOptions.multipleDays && dateType === 'from') && updateEndTimeInputMinTime(time); - setDeductionMaximumBoundary(dateType, true); - }); + }); } /** @@ -694,21 +502,6 @@ define([ return _.includes(['weekend', 'non_working_day', 'public_holiday'], dayType); } - /** - * Loads absence types and calendar data on component initialization and - * when they need to be updated. - * - * @param {Date} date - the selected date - * @param {String} dayType - set to from if from date is selected else to - * @return {Promise} - */ - function loadDayTypesForDate (date, dateType) { - return filterLeaveRequestDayTypes(date, dateType) - .then(function () { - vm.loading[dateType + 'DayTypes'] = false; - }); - } - /** * Initializes leave request day types * @@ -721,41 +514,6 @@ define([ }); } - /** - * Loads time ranges from work pattern, - * sets time ranges for timepickers and maximum value for deduction. - * - * @param {String} dateType from|to - * @return {Promise} - */ - function loadTimeRangesFromWorkPattern (dateType) { - var date = vm.uiOptions[dateType + 'Date']; - var timeObject = vm.uiOptions.times[dateType]; - var isSingleDayRequest = !vm.uiOptions.multipleDays; - - if (!date) { - return $q.resolve(); - } - - return vm.request.getWorkDayForDate(convertDateToServerFormat(date)) - .then(function (workDay) { - workDays[dateType] = workDay; - - enableAndSetDataToTimeInput(dateType, workDay); - (isSingleDayRequest && dateType === 'from') && enableAndSetDataToTimeInput('to', workDay); - }) - .catch(function (err) { - workDays[dateType] = {}; - - return handleError(err); - }) - .finally(function () { - timeObject.loading = false; - - isSingleDayRequest && (vm.uiOptions.times['to'].loading = false); - }); - } - /** * Initializes user's calendar (work patterns) * @@ -832,28 +590,19 @@ define([ ) { vm.uiOptions.toDate = null; - resetUIDayTypesTimeAndDeductions('to'); + resetUIInputs('to'); } } /** - * Reset day types, times and deductions. + * Calls extended resetting function, if any, then sets values from UI to + * the request and toggles the balance * * @param {String} dateType from|to */ - function resetUIDayTypesTimeAndDeductions (dateType) { - var time = vm.uiOptions.times[dateType]; - - vm['request' + _.startCase(dateType) + 'DayTypes'] = []; - time.time = ''; - time.min = '00:00'; - time.max = '00:00'; - time.amount = '0'; - time.maxAmount = '0'; - time.loading = false; - + function resetUIInputs (dateType) { + (vm.resetUIInputsExtended) && vm.resetUIInputsExtended(dateType); setRequestDateTimesAndDateTypes(); - setRequestHoursDeductions(); toggleBalance(); } @@ -910,44 +659,6 @@ define([ return $q.resolve().then(vm.setDaysSelectionModeExtended); } - /** - * Sets the collection for given day types to sent list of day types, - * also initializes the day types - * - * @param {String} dateType from|to - * @param {Array} listOfDayTypes collection of available day types - */ - function setDayTypes (dateType, listOfDayTypes) { - // will create either of leaveRequestFromDayTypes or leaveRequestToDayTypes key - var keyForDayTypeCollection = 'request' + _.startCase(dateType) + 'DayTypes'; - - vm[keyForDayTypeCollection] = listOfDayTypes; - - if (vm.isMode('create')) { - vm.request[dateType + '_date_type'] = vm[keyForDayTypeCollection][0].value; - } - } - - /** - * Sets deduction maximum and default amounts for a given day type - * - * @param {String} timeType from|to - * @param {Boolean} setDefaultValue if TRUE, then set the current value to maximum - */ - function setDeductionMaximumBoundary (timeType, setDefaultValue) { - var uiOptions = vm.uiOptions; - var dateType = uiOptions.multipleDays ? timeType : 'from'; - var timeObject = uiOptions.times[dateType]; - var timeFrom = uiOptions.multipleDays && dateType === 'to' ? timeObject.min : uiOptions.times.from.time; - var timeTo = uiOptions.multipleDays && dateType === 'from' ? timeObject.max : uiOptions.times.to.time; - var deduction = workDays[dateType].number_of_hours - ? getTimeDifferenceInHours(timeFrom, timeTo).toString() - : '0'; - - timeObject.maxAmount = deduction; - (setDefaultValue) && (timeObject.amount = timeObject.maxAmount); - } - /** * Updates the opening balance depending on the mode * In case of "edit" or "view" mode, sets original balance @@ -986,22 +697,12 @@ define([ vm.request.to_date_type = vm.request.from_date_type; } - if (isCalculationUnit('hours') && !isLeaveType('toil')) { + if (isCalculationUnit('hours') || isLeaveType('toil')) { vm.request.from_date = vm.request.from_date && times.from.time ? vm.request.from_date + ' ' + times.from.time : null; vm.request.to_date = vm.request.to_date && times.to.time ? vm.request.to_date + ' ' + times.to.time : null; } } - /** - * Sets deductions in hours from UI to vm.request - */ - function setRequestHoursDeductions () { - var times = vm.uiOptions.times; - - vm.request.from_date_amount = !isNaN(+times.from.amount) ? times.from.amount : null; - vm.request.to_date_amount = !isNaN(+times.to.amount) ? times.to.amount : null; - } - /** * Shows or hides the balance breakdown depending on various conditions */ @@ -1039,15 +740,9 @@ define([ return $q.resolve() .then(absenceTypeUnitChanged && setDaysSelectionMode) - .then(function () { - if (absenceTypeUnitChanged && isCalculationUnit('hours')) { - return loadTimeRangesFromWorkPattern('from') - .then(function () { - setDeductionMaximumBoundary('from', true); - }); - } - }) + .then(absenceTypeUnitChanged && vm.onAbsenceTypeUpdateExtended) .then(absenceTypeUnitChanged && setRequestDateTimesAndDateTypes) + .then(finishLoadingTimesAndDateTypes) .then(performBalanceChangeCalculation); } @@ -1068,7 +763,7 @@ define([ if (moment(vm.uiOptions.toDate).isAfter(vm.period.end_date)) { vm.uiOptions.toDate = undefined; - resetUIDayTypesTimeAndDeductions('to'); + resetUIInputs('to'); } setOpeningBalance(); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-record-actions.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-record-actions.component.js index a913af5cbcb..8f7cf0ec81e 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-record-actions.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/leave-request-record-actions.component.js @@ -7,10 +7,9 @@ define([ ], function (components) { components.component('leaveRequestRecordActions', { bindings: { - btnClass: '@', contactId: '<', - selectedContactId: '<', - isSelfRecord: '<' + isSelfRecord: '<', + selectedContactId: '<' }, templateUrl: ['shared-settings', function (sharedSettings) { return sharedSettings.sharedPathTpl + 'components/leave-request-record-actions.html'; @@ -27,8 +26,7 @@ define([ vm.leaveRequestOptions = [ { type: 'leave', icon: 'briefcase', label: 'Leave' }, - { type: 'sickness', icon: 'stethoscope', label: 'Sickness' }, - { type: 'toil', icon: 'calendar-plus-o', label: 'Overtime' } + { type: 'sickness', icon: 'stethoscope', label: 'Sickness' } ]; vm.openLeavePopup = openLeavePopup; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/staff-leave-report.component.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/staff-leave-report.component.js index e008e89e071..f48b81b8c2f 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/staff-leave-report.component.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/components/staff-leave-report.component.js @@ -22,8 +22,8 @@ define([ }); function controller ($log, $q, $rootScope, checkPermissions, AbsencePeriod, - AbsenceType, Entitlement, LeaveRequest, OptionGroup, pubSub, - HRSettings, sharedSettings) { + AbsenceType, Entitlement, LeaveRequest, OptionGroup, pubSub, + HRSettings, sharedSettings) { $log.debug('Component: staff-leave-report'); var statusUpdateHandlers = { @@ -63,18 +63,18 @@ define([ loadAbsenceTypes(), loadAbsencePeriods() ]) - .then(function () { - vm.loading.page = false; - }) - .then(function () { - return $q.all([ - loadEntitlements(), - loadBalanceChanges() - ]); - }) - .then(function () { - vm.loading.content = false; - }); + .then(function () { + vm.loading.page = false; + }) + .then(function () { + return $q.all([ + loadEntitlements(), + loadBalanceChanges() + ]); + }) + .then(function () { + vm.loading.content = false; + }); registerEvents(); })(); @@ -210,15 +210,15 @@ define([ valueOfRequestStatus(sharedSettings.statusNames.moreInformationRequired) ]) ]) - .then(function (results) { - vm.absenceTypes.forEach(function (absenceType) { - absenceType.balanceChanges = { - holidays: results[0][absenceType.id], - approved: results[1][absenceType.id], - pending: results[2][absenceType.id] - }; + .then(function (results) { + vm.absenceTypes.forEach(function (absenceType) { + absenceType.balanceChanges = { + holidays: results[0][absenceType.id], + approved: results[1][absenceType.id], + pending: results[2][absenceType.id] + }; + }); }); - }); } /** @@ -234,24 +234,24 @@ define([ contact_id: vm.contactId, period_id: vm.selectedPeriod.id }, true) - .then(function (entitlements) { - vm.entitlements = entitlements; - }) - .then(function () { - vm.absenceTypesFiltered = vm.absenceTypes.filter(function (absenceType) { - var entitlement = _.find(vm.entitlements, function (entitlement) { - return entitlement.type_id === absenceType.id; - }); + .then(function (entitlements) { + vm.entitlements = entitlements; + }) + .then(function () { + vm.absenceTypesFiltered = vm.absenceTypes.filter(function (absenceType) { + var entitlement = _.find(vm.entitlements, function (entitlement) { + return entitlement.type_id === absenceType.id; + }); - // set entitlement to 0 if no entitlement is present - absenceType.entitlement = entitlement ? entitlement.value : 0; - absenceType.remainder = entitlement ? entitlement.remainder : { current: 0, future: 0 }; + // set entitlement to 0 if no entitlement is present + absenceType.entitlement = entitlement ? entitlement.value : 0; + absenceType.remainder = entitlement ? entitlement.remainder : { current: 0, future: 0 }; - return !((absenceType.entitlement === 0) && + return !((absenceType.entitlement === 0) && (absenceType.allow_overuse !== '1') && (absenceType.allow_accruals_request !== '1')); + }); }); - }); } /** @@ -264,12 +264,12 @@ define([ contact_id: vm.contactId, period_id: vm.selectedPeriod.id }, vm.entitlements) - .then(function () { - return processBreakdownsList(vm.entitlements); - }) - .then(function (breakdownListFlatten) { - vm.sections.entitlements.data = breakdownListFlatten; - }); + .then(function () { + return processBreakdownsList(vm.entitlements); + }) + .then(function (breakdownListFlatten) { + vm.sections.entitlements.data = breakdownListFlatten; + }); } /** @@ -372,7 +372,7 @@ define([ status_id: { in: [ valueOfRequestStatus(sharedSettings.statusNames.awaitingApproval), valueOfRequestStatus(sharedSettings.statusNames.moreInformationRequired) - ] }, + ] } }); } @@ -497,7 +497,10 @@ define([ return dataEntry.id === leaveRequest.id; }); delete section.dataIndex[leaveRequest.id]; - updateSectionNumbersWithLeaveRequestBalanceChange(leaveRequest, sectionName); + + if (sectionName !== 'other') { + updateSectionNumbersWithLeaveRequestBalanceChange(leaveRequest, sectionName); + } }); } @@ -509,11 +512,15 @@ define([ * @param {string} section */ function updateSectionNumbersWithLeaveRequestBalanceChange (leaveRequest, section) { + var remaindersToUpdate = ['future', 'current']; var absenceType = vm.absenceTypesIndexed[leaveRequest.type_id]; - var remainderType = (section === 'pending') ? 'future' : 'current'; + + (section === 'pending') && _.pull(remaindersToUpdate, 'current'); absenceType.balanceChanges[section] -= leaveRequest.balance_change; - absenceType.remainder[remainderType] -= leaveRequest.balance_change; + remaindersToUpdate.forEach(function (remainder) { + absenceType.remainder[remainder] -= leaveRequest.balance_change; + }); } /** @@ -527,15 +534,15 @@ define([ loadEntitlements(), loadBalanceChanges() ]) - .then(function () { - vm.loading.content = false; - }) - .then(function () { - return $q.all([ - loadOpenSectionsData(), - clearSectionsData() - ]); - }); + .then(function () { + vm.loading.content = false; + }) + .then(function () { + return $q.all([ + loadOpenSectionsData(), + clearSectionsData() + ]); + }); } /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/request.controller.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/request.controller.js index 003b015ad3a..852a7e022ad 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/request.controller.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/request.controller.js @@ -667,8 +667,8 @@ define([ var requestFromDate = moment(request.from_date); var requestToDate = moment(request.to_date); - return (requestFromDate.isSameOrAfter(period.start_date) && - requestToDate.isSameOrBefore(period.end_date)); + return (requestFromDate.isSameOrAfter(period.start_date, 'day') && + requestToDate.isSameOrBefore(period.end_date, 'day')); } /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller.js index 7a212012335..42ebeefbb37 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-leave.controller.js @@ -1,19 +1,30 @@ /* eslint-env amd */ define([ + 'common/lodash', + 'common/moment', 'leave-absences/shared/modules/controllers' -], function (controllers) { +], function (_, moment, controllers) { controllers.controller('RequestModalDetailsLeaveController', RequestModalDetailsLeaveController); - RequestModalDetailsLeaveController.$inject = ['$controller', '$log', '$q', 'detailsController']; + RequestModalDetailsLeaveController.$inject = ['$controller', '$log', '$q', '$rootScope', 'detailsController', 'PublicHoliday', 'LeaveRequest']; + + function RequestModalDetailsLeaveController ($controller, $log, $q, $rootScope, detailsController, PublicHoliday, LeaveRequest) { + var workDays = {}; - function RequestModalDetailsLeaveController ($controller, $log, $q, detailsController) { $log.debug('RequestModalDetailsLeaveController'); detailsController.calculateBalanceChange = calculateBalanceChange; detailsController.canCalculateChange = canCalculateChange; detailsController.canSubmit = canSubmit; detailsController.initChildController = initChildController; + detailsController.initDayTypesExtended = initDayTypes; + detailsController.initTimesExtended = initTimes; + detailsController.initWatchersExtended = initWatchers; + detailsController.onAbsenceTypeUpdateExtended = updateFromTimeRangeAndDeductionBoundary; + detailsController.onDateChangeExtended = loadDayTypesTimeRangesAndSetDeductionBoundaries; + detailsController.resetUIInputsExtended = resetUITimesDayTypesAndDeductions; + detailsController.setDaysSelectionModeExtended = setDaysSelectionModeExtended; /** * Calculates balance change by fetching the balance breakdown via the API @@ -57,6 +68,131 @@ define([ return detailsController.canCalculateChange(); } + /** + * Enables a time input of the specified type + * and sets provided data such as minumum and maximum time values and time + * + * @param {String} type from|to + */ + function enableAndSetDataToTimeInput (type, data) { + var timeObject = detailsController.uiOptions.times[type]; + var timeMin = _.clone(data.time_from); + var timeMax = _.clone(data.time_to); + + if (!detailsController.uiOptions.multipleDays) { + if (type === 'from' && timeMax && timeMin) { + timeMax = detailsController.getMomentDateWithGivenTime(timeMax) + .subtract(detailsController.uiOptions.time_interval, 'minutes') + .format('HH:mm'); + } + if (type === 'to' && timeMin && timeMax) { + timeMin = detailsController.getMomentDateWithGivenTime(timeMin) + .add(detailsController.uiOptions.time_interval, 'minutes') + .format('HH:mm'); + } + } + + timeObject.min = timeMin || '00:00'; + timeObject.max = timeMax || '00:00'; + timeObject.time = type === 'to' ? timeObject.max : timeObject.min; + } + + /** + * This method will be used on the view to return a list of available + * leave request day types (All day, Half-day AM, Half-day PM, Non working day, + * Weekend, Public holiday) for the given date (which is the date + * selected by the user via datepicker) + * + * If no date is passed, then no list is returned + * + * @param {Date} date + * @param {String} dayType - set to from if from date is selected else to + * @return {Promise} of array with day types + */ + function filterLeaveRequestDayTypes (date, dayType) { + if (!date) { + return $q.reject([]); + } + + date = detailsController.convertDateToServerFormat(date); + + return hasDatePublicHolidayRequest(date) + .then(function (result) { + if (result) { + return detailsController.requestDayTypes.filter(function (publicHoliday) { + return publicHoliday.name === 'public_holiday'; + }); + } + + return getDayTypesFromDate(date, detailsController.requestDayTypes) + .then(function (inCalendarList) { + return inCalendarList.length + ? inCalendarList + : detailsController.requestDayTypes.filter(function (dayType) { + return _.includes(['all_day', 'half_day_am', 'half_day_pm'], dayType.name); + }); + }); + }) + .then(function (dayTypes) { + setDayTypes(dayType, dayTypes); + + return dayTypes; + }); + } + + /** + * Gets list of day types if its found to be weekend or non working in calendar + * + * @param {Date} date to Checks + * @param {Array} listOfDayTypes array of day types + * @return {Array} non-empty if found else empty array + */ + function getDayTypesFromDate (date, listOfDayTypes) { + date = moment(date); + + return $q.all([ + detailsController.calendar.isNonWorkingDay(date), + detailsController.calendar.isWeekend(date) + ]).then(function (results) { + return results[0] ? 'non_working_day' : (results[1] ? 'weekend' : null); + }).then(function (nameFilter) { + return !nameFilter ? [] : listOfDayTypes.filter(function (day) { + return day.name === nameFilter; + }); + }); + } + + /** + * Calculates time difference in hours + * + * @param {String} timeFrom in HH:mm format + * @param {String} timeTo in HH:mm format + * @return {Number} amount of hours, eg. 7.5 + */ + function getTimeDifferenceInHours (timeFrom, timeTo) { + return moment.duration(timeTo) + .subtract(moment.duration(timeFrom)).asHours(); + } + + /** + * Checks if a "public holiday" request exists for the given date, for the + * currently selected contact + * + * @param {String} date + * @return {Promise} resolves to {Boolean} + */ + function hasDatePublicHolidayRequest (date) { + return LeaveRequest.all({ + public_holiday: 1, + contact_id: detailsController.request.contact_id, + from_date: { from: date }, + to_date: { to: date } + }) + .then(function (result) { + return !!result.list.length; + }); + } + /** * Initialize the controller * @@ -65,5 +201,286 @@ define([ function initChildController () { return $q.resolve(); } + + function initDayTypes () { + return loadDayTypesForDate(detailsController.uiOptions.fromDate, 'from') + .then(function () { + return loadDayTypesForDate(detailsController.uiOptions.toDate, 'to'); + }); + } + + /** + * Initialises a watcher for a custom deduction input of a specified date type + * + * @param {String} dateType from|to + */ + function initDeductionInputWatcher (dateType) { + $rootScope.$watch(function () { + return detailsController.uiOptions.times[dateType].amount; + }, function (amount, oldAmount) { + if (detailsController.isCalculationUnit('days') || +amount === +oldAmount) { + return; + } + + if (detailsController.isRole('staff')) { + detailsController.request.change_balance = true; + } + + setRequestHoursDeductions(); + // @NOTE `detailsController.` is needed for testing purposes + detailsController.performBalanceChangeCalculation(); + }); + } + + /** + * Initialises time for a given date type. + * In general cases simply extracts the time from the date string and + * sets the time to the correspondent times property. + * If the time is outside the allowed range (for example after work parrern change), + * then it sets the minimum allowed time for "from" time + * and the maximum allowed time for "to" time. + * + * @param {String} dateType from|to + */ + function initTime (dateType) { + var time = moment(detailsController.request[dateType + '_date']).format('HH:mm'); + var timeObject = detailsController.uiOptions.times[dateType]; + var isOutsideWorkPatternRange = + getTimeDifferenceInHours(timeObject.min, time) <= 0 || + getTimeDifferenceInHours(timeObject.max, time) >= 0; + + if (isOutsideWorkPatternRange) { + time = dateType === 'from' ? timeObject.min : timeObject.max; + } + + detailsController.uiOptions.times[dateType].time = time; + } + + /** + * Initialises and sets the "from" and "to" times + * + * @return {Promise} + */ + function initTimes () { + var dateTypes = detailsController.uiOptions.multipleDays ? ['from', 'to'] : ['from']; + var times = detailsController.uiOptions.times; + + if (!detailsController.isCalculationUnit('hours')) { + return; + } + + return $q.all(dateTypes.map(loadTimeRangesFromWorkPattern)) + .then(function () { + ['from', 'to'].forEach(function (dateType) { + initTime(dateType); + + setDeductionMaximumBoundary(dateType); + + times[dateType].amount = + Math.min(detailsController.request[dateType + '_date_amount'], times[dateType].maxAmount).toString(); + }); + + if (!detailsController.uiOptions.multipleDays) { + detailsController.updateEndTimeInputMinTime(detailsController.uiOptions.times.from.time); + } + }).then(setRequestHoursDeductions); + } + + /** + * Initialises watchers for time and deductions inputs + */ + function initWatchers () { + ['from', 'to'].forEach(function (dateType) { + initDeductionInputWatcher(dateType); + initTimeInputWatcher(dateType); + }); + } + + /** + * Initialises a watcher for a time input of a specified date type + * + * @param {String} dateType from|to + */ + function initTimeInputWatcher (dateType) { + $rootScope.$watch(function () { + return detailsController.uiOptions.times[dateType].time; + }, function (time, oldTime) { + if (detailsController.isCalculationUnit('days') || time === oldTime) { + return; + } + + detailsController.setRequestDateTimesAndDateTypes(); + + if (!time) { + return; + } + + setDeductionMaximumBoundary(dateType, true); + }); + } + + /** + * Loads absence types and calendar data on component initialization and + * when they need to be updated. + * + * @param {Date} date - the selected date + * @param {String} dayType - set to from if from date is selected else to + * @return {Promise} + */ + function loadDayTypesForDate (date, dateType) { + return filterLeaveRequestDayTypes(date, dateType) + .then(function () { + detailsController.loading[dateType + 'DayTypes'] = false; + }); + } + + function loadDayTypesTimeRangesAndSetDeductionBoundaries (dateType) { + return loadDayTypesForDate(detailsController.uiOptions[dateType + 'Date'], dateType) + .then(function () { + if (detailsController.isCalculationUnit('hours')) { + return loadTimeRangesFromWorkPattern(dateType) + .then(function () { + setDeductionMaximumBoundary(dateType, true); + }); + } + }); + } + + /** + * Loads time ranges from work pattern, + * sets time ranges for timepickers and maximum value for deduction. + * + * @param {String} dateType from|to + * @return {Promise} + */ + function loadTimeRangesFromWorkPattern (dateType) { + var date = detailsController.uiOptions[dateType + 'Date']; + var isSingleDayRequest = !detailsController.uiOptions.multipleDays; + + if (!date) { + return $q.resolve(); + } + + return detailsController.request.getWorkDayForDate(detailsController.convertDateToServerFormat(date)) + .then(function (workDay) { + workDays[dateType] = workDay; + + enableAndSetDataToTimeInput(dateType, workDay); + (isSingleDayRequest && dateType === 'from') && enableAndSetDataToTimeInput('to', workDay); + }) + .catch(function (err) { + workDays[dateType] = {}; + + return detailsController.handleError(err); + }) + .finally(function () { + detailsController.uiOptions.times[dateType].loading = false; + + isSingleDayRequest && (detailsController.uiOptions.times['to'].loading = false); + }); + } + + /** + * Resets time input, day types and deduction for a given date type + * + * @param {String} dateType (from|to) + */ + function resetUITimesDayTypesAndDeductions (dateType) { + var timeObject = detailsController.uiOptions.times[dateType]; + + detailsController['request' + _.startCase(dateType) + 'DayTypes'] = []; + timeObject.time = ''; + timeObject.min = '00:00'; + timeObject.max = '00:00'; + timeObject.amount = '0'; + timeObject.maxAmount = '0'; + } + + /** + * Sets the collection for given day types to sent list of day types, + * also initializes the day types + * + * @param {String} dateType from|to + * @param {Array} listOfDayTypes collection of available day types + */ + function setDayTypes (dateType, listOfDayTypes) { + // will create either of leaveRequestFromDayTypes or leaveRequestToDayTypes key + var keyForDayTypeCollection = 'request' + _.startCase(dateType) + 'DayTypes'; + + detailsController[keyForDayTypeCollection] = listOfDayTypes; + + if (detailsController.isMode('create')) { + detailsController.request[dateType + '_date_type'] = detailsController[keyForDayTypeCollection][0].value; + } + } + + /** + * Updates time ranges as per the work pattern for "from" date + * and updates the deduction fields boundaries + * + * @NOTE In case of a single day, also show "to" time loading + * + * @return {Promise} + */ + function setDaysSelectionModeExtended () { + if (!detailsController.isCalculationUnit('hours') || !detailsController.uiOptions.fromDate) { + return $q.resolve(); + } + + detailsController.disableAndShowLoadingTimeInput('from'); + (!detailsController.uiOptions.multipleDays) && detailsController.disableAndShowLoadingTimeInput('to'); + + return loadTimeRangesFromWorkPattern('from') + .then(function () { + setDeductionMaximumBoundary('from', true); + }); + } + + /** + * Sets deduction maximum and default amounts for a given day type + * + * @param {String} timeType from|to + * @param {Boolean} setDefaultValue if TRUE, then set the current value to maximum + */ + function setDeductionMaximumBoundary (timeType, setDefaultValue) { + var uiOptions = detailsController.uiOptions; + var dateType = uiOptions.multipleDays ? timeType : 'from'; + var timeObject = uiOptions.times[dateType]; + var timeFrom = uiOptions.multipleDays && dateType === 'to' ? timeObject.min : uiOptions.times.from.time; + var timeTo = uiOptions.multipleDays && dateType === 'from' ? timeObject.max : uiOptions.times.to.time; + var deduction = workDays[dateType].number_of_hours + ? getTimeDifferenceInHours(timeFrom, timeTo).toString() + : '0'; + + timeObject.maxAmount = deduction; + (setDefaultValue) && (timeObject.amount = timeObject.maxAmount); + } + + /** + * Sets deductions in hours from UI to detailsController.request + */ + function setRequestHoursDeductions () { + var times = detailsController.uiOptions.times; + + detailsController.request.from_date_amount = !isNaN(+times.from.amount) ? times.from.amount : null; + detailsController.request.to_date_amount = !isNaN(+times.to.amount) ? times.to.amount : null; + } + + /** + * Updates time ranges as per the work pattern for "from" date + * and updates the deduction fields boundaries + * + * @return {Promise} + */ + function updateFromTimeRangeAndDeductionBoundary () { + if (!detailsController.isCalculationUnit('hours') || !detailsController.uiOptions.fromDate) { + return $q.resolve(); + } + + return loadTimeRangesFromWorkPattern('from') + .then(function () { + setDeductionMaximumBoundary('from', true); + }); + } } }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller.js index e7d812099d5..7372b855d02 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-sickness.controller.js @@ -6,9 +6,11 @@ define([ ], function (_, controllers) { controllers.controller('RequestModalDetailsSicknessController', RequestModalDetailsSicknessController); - RequestModalDetailsSicknessController.$inject = ['$controller', '$log', '$q', 'api.optionGroup', 'detailsController']; + RequestModalDetailsSicknessController.$inject = ['$controller', '$log', '$q', '$rootScope', + 'crmAngService', 'api.optionGroup', 'detailsController']; - function RequestModalDetailsSicknessController ($controller, $log, $q, OptionGroup, detailsController) { + function RequestModalDetailsSicknessController ($controller, $log, $q, $rootScope, crmAngService, + OptionGroup, detailsController) { $log.debug('RequestModalDetailsSicknessController'); // Shares basic logic with the the leave controller $controller('RequestModalDetailsLeaveController', { detailsController: detailsController }); @@ -17,6 +19,7 @@ define([ detailsController.initChildController = initChildController; detailsController.isChecked = isChecked; detailsController.isDocumentInRequest = isDocumentInRequest; + detailsController.openSicknessReasonOptionsEditor = openSicknessReasonOptionsEditor; /** * Checks if submit button can be enabled for user and returns true if successful @@ -35,7 +38,8 @@ define([ function initChildController () { return $q.all([ loadDocuments(), - loadReasons() + toggleSicknessReasonsEditorIcon(), + loadReasons(true) ]); } @@ -84,11 +88,26 @@ define([ * * @return {Promise} */ - function loadReasons () { - return OptionGroup.valuesOf('hrleaveandabsences_sickness_reason') + function loadReasons (cache) { + return OptionGroup.valuesOf('hrleaveandabsences_sickness_reason', cache) .then(function (reasons) { detailsController.sicknessReasons = _.indexBy(reasons, 'name'); }); } + + /** + * Opens editor for sickness reason options editing + */ + function openSicknessReasonOptionsEditor () { + crmAngService.loadForm('/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1') + .on('crmUnload', function () { + loadReasons(false); + }); + } + + function toggleSicknessReasonsEditorIcon() { + detailsController.showSicknessOptionsEditorIcon = + _.includes(['admin-dashboard', 'absence-tab'], $rootScope.section); + } } }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller.js index 95e1e229e34..f805af1e5af 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/controllers/sub-controllers/request-modal-details-toil.controller.js @@ -2,35 +2,45 @@ define([ 'common/lodash', + 'common/moment', 'leave-absences/shared/modules/controllers' -], function (_, controllers) { +], function (_, moment, controllers) { controllers.controller('RequestModalDetailsToilController', RequestModalDetailsToilController); - RequestModalDetailsToilController.$inject = ['$log', '$q', '$rootScope', 'api.optionGroup', 'AbsenceType', 'detailsController']; + RequestModalDetailsToilController.$inject = ['$log', '$q', '$rootScope', + 'crmAngService', 'OptionGroup', 'AbsenceType', 'detailsController']; - function RequestModalDetailsToilController ($log, $q, $rootScope, OptionGroup, AbsenceType, detailsController) { + function RequestModalDetailsToilController ($log, $q, $rootScope, + crmAngService, OptionGroup, AbsenceType, detailsController) { $log.debug('RequestModalDetailsToilController'); var initialRequestAttributes; + var skipSettingDefaultDuration = !detailsController.isMode('create'); var expirationConditions = { hasPreviousExpirationDate: null, hasExpirationFromAdminSettings: null }; detailsController.canDisplayToilExpirationField = false; - detailsController.calculateBalanceChange = calculateBalanceChange; detailsController.canCalculateChange = canCalculateChange; detailsController.canSubmit = canSubmit; detailsController.clearExpiryDate = clearExpiryDate; detailsController.initChildController = initChildController; - detailsController.onDateChangeExtended = tryToCalculateExpiryDate; - detailsController.setDaysSelectionModeExtended = tryToCalculateExpiryDate; + detailsController.initTimesExtended = initTimes; + detailsController.initWatchersExtended = initWatchers; + detailsController.onAbsenceTypeUpdateExtended = onAbsenceTypeUpdateHandler; + detailsController.onDateChangeExtended = onDateChangeHandler; + detailsController.openToilInDaysAccrualOptionsEditor = openToilInDaysAccrualOptionsEditor; + detailsController.resetUIInputsExtended = resetTime; + detailsController.setDaysSelectionModeExtended = onDaysSelectionModeHandler; detailsController.updateExpiryDate = updateExpiryDate; (function init () { - initAccrueValueWatcher(); setInitialRequestAttributes(); + setTimeInputsRanges(); + toggleAccrualOptionsGroupEditorIcon(); + !detailsController.isMode('create') && initDuration(); })(); /** @@ -45,6 +55,21 @@ define([ return $q.resolve(detailsController.balance.change); } + /** + * Calculates the TOIL maximum duration and sets its default value + */ + function calculateDuration () { + if (!detailsController.request.from_date || !detailsController.request.to_date) { + detailsController.uiOptions.max_toil_duration_and_accrual = null; + detailsController.uiOptions.toil_duration_in_hours = null; + + return; + } + + detailsController.uiOptions.max_toil_duration_and_accrual = + moment.duration(moment(detailsController.request.to_date).diff(detailsController.request.from_date)).asHours(); + } + /** * Calculates the TOIL expiry date and updates the UI and the Request's * expiry date value. @@ -159,7 +184,7 @@ define([ if (!field.value) { return $q.reject([]); } else { - return $q.resolve(field.value); + return $q.resolve(moment(field.value).format('YYYY-MM-DD')); } } @@ -181,6 +206,15 @@ define([ ); } + /** + * Initialises duration by converting it from minutes to hours + * and setting to a separate variable in UI options + */ + function initDuration () { + detailsController.uiOptions.toil_duration_in_hours = + detailsController.request.toil_duration / 60; + } + /** * Initialises the expiration conditions for the current toil request * using the following rules: @@ -229,10 +263,6 @@ define([ * When accrue value changes it, if possible, calculates the balance change. */ function initAccrueValueWatcher () { - if (detailsController.isMode('view')) { - return; - } - $rootScope.$watch( function () { return detailsController.request.toil_to_accrue; @@ -244,23 +274,204 @@ define([ }); } + /** + * Initialises watcher for Duration value. + * When Duration value changes, it sets this value to the Accrual as well. + */ + function initDurationValueWatcher () { + $rootScope.$watch( + function () { + return detailsController.uiOptions.toil_duration_in_hours; + }, + function (oldValue, newValue) { + if (oldValue !== newValue && detailsController.isCalculationUnit('hours')) { + setDefaultAccrualValue(); + } + + detailsController.request.toil_duration = + detailsController.uiOptions.toil_duration_in_hours + ? detailsController.uiOptions.toil_duration_in_hours * 60 + : null; + }); + } + + /** + * Initialises and sets the "from" and "to" times + * + * @return {Promise} + */ + function initTimes () { + var times = detailsController.uiOptions.times; + + times.from.time = moment(detailsController.request.from_date).format('HH:mm'); + times.to.time = moment(detailsController.request.to_date).format('HH:mm'); + + if (!detailsController.uiOptions.multipleDays) { + detailsController.updateEndTimeInputMinTime(detailsController.uiOptions.times.from.time); + } + } + + /** + * Initialises watcher for times values. + * The values of time fields define the maximum and default Duration values. + */ + function initTimesWatcher () { + ['from', 'to'].forEach(function (dateType) { + $rootScope.$watch( + function () { + return detailsController.uiOptions.times[dateType].time; + }, + function (oldValue, newValue) { + if (oldValue === newValue) { + return; + } + + detailsController.setRequestDateTimesAndDateTypes(); + tryToCalculateExpiryDate(); + calculateDuration(); + setDefaultDuration(); + }); + }); + } + + /** + * Initialises watchers for Accruals and Duration values + */ + function initWatchers () { + if (detailsController.isMode('view')) { + return; + } + + initAccrueValueWatcher(); + initDurationValueWatcher(); + initTimesWatcher(); + } + /** * Initializes leave request toil amounts * + * @param {Boolean} cache if to cache results of the API call, cache by default * @return {Promise} */ - function loadToilAmounts () { - return OptionGroup.valuesOf('hrleaveandabsences_toil_amounts') + function loadToilAmounts (cache) { + return OptionGroup.valuesOf('hrleaveandabsences_toil_amounts', cache) .then(function (amounts) { - detailsController.toilAmounts = _.indexBy(amounts, 'value'); + detailsController.toilAmounts = _.sortBy(amounts, function (amount) { + return +amount.weight; + }); }); } + /** + * Handles the dates change + */ + function onDateChangeHandler () { + calculateDuration(); + setDefaultDuration(); + + return tryToCalculateExpiryDate(); + } + + /** + * Handles the days selection mode change + */ + function onDaysSelectionModeHandler () { + setTimeInputsRanges(); + + if (!detailsController.uiOptions.multipleDays) { + detailsController.updateEndTimeInputMinTime(detailsController.uiOptions.times.from.time); + } + + calculateDuration(); + !skipSettingDefaultDuration ? setDefaultDuration() : (skipSettingDefaultDuration = false); + + return tryToCalculateExpiryDate(); + } + + /** + * Resets time in UI for a given date type + * + * @param {String} dateType from|todo + */ + function resetTime (dateType) { + detailsController.uiOptions.times[dateType].time = ''; + } + + /** + * Sets default accrual value based on the duration. + */ + function setDefaultAccrualValue () { + detailsController.request.toil_to_accrue = + detailsController.uiOptions.toil_duration_in_hours; + } + + /** + * Sets default duration as a maximum allowed duration value + */ + function setDefaultDuration () { + detailsController.uiOptions.toil_duration_in_hours = + detailsController.uiOptions.max_toil_duration_and_accrual; + } + /** * Stores the initial request attributes to determine if there has been a change. */ function setInitialRequestAttributes () { - initialRequestAttributes = angular.copy(detailsController.request.attributes()); + initialRequestAttributes = _.cloneDeep(detailsController.request.attributes()); + } + + /** + * Sets ranges for both start and end times depending on the day selection mode + */ + function setTimeInputsRanges () { + if (detailsController.uiOptions.multipleDays) { + ['from', 'to'].forEach(function (dateType) { + detailsController.uiOptions.times[dateType].min = '00:00'; + detailsController.uiOptions.times[dateType].max = '23:45'; + }); + } else { + detailsController.uiOptions.times.from.min = '00:00'; + detailsController.uiOptions.times.from.max = '23:30'; + detailsController.uiOptions.times.to.min = '00:15'; + detailsController.uiOptions.times.to.max = '23:45'; + } + } + + /** + * Handles absence type change. Calculates TOIL duration and sets its default value. + * Sets accrual value if unit is in hours, otherwise, flushes it. + */ + function onAbsenceTypeUpdateHandler () { + detailsController.setRequestDateTimesAndDateTypes(); + calculateDuration(); + setDefaultDuration(); + + if (detailsController.isCalculationUnit('hours')) { + setDefaultAccrualValue(); + } else { + detailsController.request.toil_to_accrue = null; + } + } + + /** + * Opens the CRM modal that allows to edit TOIL in days amounts options + * and reloads these options in the Leave Request Modal + * if they are changed via the CRM modal + */ + function openToilInDaysAccrualOptionsEditor () { + crmAngService.loadForm('/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1') + .on('crmUnload', function () { + loadToilAmounts(false); + }); + } + + /** + * Toggles the TOIL accrual options group editor icon + * depending on the site section the Leave Request Modal is opened at + */ + function toggleAccrualOptionsGroupEditorIcon () { + detailsController.showTOILAccrualsOptionEditorIcon = + _.includes(['admin-dashboard', 'absence-tab'], $rootScope.section); } /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/instances/toil-request.instance.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/instances/toil-request.instance.js index ab817222b97..ece16847ea9 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/instances/toil-request.instance.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/src/leave-absences/shared/instances/toil-request.instance.js @@ -21,37 +21,14 @@ define([ */ defaultCustomData: function () { var toilCustomData = { - toilDurationHours: '0', - toilDurationMinutes: '0', + from_date_amount: 0, + to_date_amount: 0, request_type: 'toil' }; return _.assign({}, LeaveRequestInstance.defaultCustomData(), toilCustomData); }, - /** - * Sets the duration hours and minutes from toil_duration on instantiation. - * - * @param {Object} attributes that need to be transformed - * @return {Object} updated attributes object - */ - transformAttributes: function (attributes) { - var duration = Number(attributes.toil_duration); - if (duration) { - attributes.toilDurationHours = Math.floor(duration / 60).toString(); - attributes.toilDurationMinutes = (duration % 60).toString(); - } - - return attributes; - }, - - /** - * Update duration - */ - updateDuration: function () { - this.toil_duration = Number(this.toilDurationHours) * 60 + Number(this.toilDurationMinutes); - }, - /** * Override of parent method * @@ -59,7 +36,7 @@ define([ * @param {string} key - The property name */ toAPIFilter: function (result, __, key) { - if (!_.includes(['balance_change', 'dates', 'comments', 'files', 'toilDurationHours', 'toilDurationMinutes'], key)) { + if (!_.includes(['balance_change', 'dates', 'comments', 'files'], key)) { result[key] = this[key]; } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-custom-work-pattern-modal.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-custom-work-pattern-modal.component.spec.js index e06748e339d..88424302b36 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-custom-work-pattern-modal.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-custom-work-pattern-modal.component.spec.js @@ -8,7 +8,7 @@ 'leave-absences/mocks/data/work-pattern.data', 'leave-absences/mocks/apis/work-pattern-api-mock', 'leave-absences/absence-tab/app' - ], function (angular, _, optionGroupMock, workPatternData) { + ], function (angular, _, optionGroupMock, workPatternData, crmAngService) { 'use strict'; describe('absenceTabWorkPatterns', function () { @@ -22,19 +22,20 @@ beforeEach(inject(function (WorkPatternAPIMock) { $provide.value('WorkPatternAPI', WorkPatternAPIMock); })); - beforeEach(inject(function (_$componentController_, _$log_, _$q_, _$rootScope_, _OptionGroup_, _WorkPatternAPI_) { + beforeEach(inject(function (_$componentController_, _$log_, _$q_, _$rootScope_, _OptionGroup_, _WorkPatternAPI_, _crmAngService_) { $componentController = _$componentController_; $log = _$log_; $q = _$q_; $rootScope = _$rootScope_; OptionGroup = _OptionGroup_; + crmAngService = _crmAngService_; WorkPatternAPI = _WorkPatternAPI_; spyOn($log, 'debug'); spyOn(WorkPatternAPI, 'get').and.callThrough(); spyOn(OptionGroup, 'valuesOf').and.callFake(function () { - return $q.resolve(optionGroupMock.getCollection('hrjc_revision_change_reason')); + return $q.resolve(optionGroupMock.getCollection('hrleaveandabsences_work_pattern_change_reason')); }); compileComponent(); @@ -49,8 +50,12 @@ }); describe('init()', function () { + it('fetches values of the Work Pattern Change Reason option group', function () { + expect(OptionGroup.valuesOf).toHaveBeenCalledWith('hrleaveandabsences_work_pattern_change_reason', true); + }); + it('loads change reasons', function () { - expect(controller.changeReasons).toEqual(optionGroupMock.getCollection('hrjc_revision_change_reason')); + expect(controller.changeReasons).toEqual(optionGroupMock.getCollection('hrleaveandabsences_work_pattern_change_reason')); }); it('loads work patterns', function () { @@ -137,6 +142,28 @@ }); }); + describe('when users click on the reason for change wrench icon', function () { + var onPopupFormSuccess; + var url = '/civicrm/admin/options/hrleaveandabsences_work_pattern_change_reason?reset=1'; + + beforeEach(function () { + spyOn(crmAngService, 'loadForm').and.callFake(function () { + return { + on: function (event, callback) { + if (event === 'crmUnload') { + onPopupFormSuccess = callback; + } + } + }; + }); + controller.openWorkPatternChangeReasonEditor(); + }); + + it('calls the crmAngService with the requested url', function () { + expect(crmAngService.loadForm).toHaveBeenCalledWith(url); + }); + }); + function compileComponent () { controller = $componentController('absenceTabCustomWorkPatternModal', null, { contactId: CRM.vars.leaveAndAbsences.contactId, diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-work-patterns.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-work-patterns.component.spec.js index 4a3c1d3b660..bf1befc94ff 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-work-patterns.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/absence-tab/components/absence-tab-work-patterns.component.spec.js @@ -34,7 +34,7 @@ WorkPattern = _WorkPattern_; spyOn(OptionGroup, 'valuesOf').and.callFake(function () { - return $q.resolve(optionGroupMock.getCollection('hrjc_revision_change_reason')); + return $q.resolve(optionGroupMock.getCollection('hrleaveandabsences_work_pattern_change_reason')); }); spyOn($log, 'debug'); @@ -47,13 +47,17 @@ describe('init()', function () { describe('when custom Work patterns are present', function () { + it('fetches values of the Work Pattern Change Reason option group', function () { + expect(OptionGroup.valuesOf).toHaveBeenCalledWith('hrleaveandabsences_work_pattern_change_reason'); + }); + it('Loads custom Work patterns', function () { expect(controller.customWorkPatterns.length).toEqual(workPatternData.workPatternsOf.values.length); }); it('Assign correct change reason label', function () { _.each(controller.customWorkPatterns, function (customWorkpattern) { - var changeReasonLabel = optionGroupMock.getCollection('hrjc_revision_change_reason').find(function (reason) { + var changeReasonLabel = optionGroupMock.getCollection('hrleaveandabsences_work_pattern_change_reason').find(function (reason) { return customWorkpattern.change_reason === reason.value; }).label; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/data/option-group.data.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/data/option-group.data.js index fce76f3e0f2..723dbd3639a 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/data/option-group.data.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/data/option-group.data.js @@ -681,6 +681,18 @@ define([ 'is_reserved': '1', 'is_active': '1' }, + { + 'id': '1147', + 'option_group_id': '146', + 'label': '1 3/4 Days', + 'value': '1.75', + 'name': 'one_and_three_quarters_days', + 'is_default': '0', + 'weight': '8', + 'is_optgroup': '0', + 'is_reserved': '1', + 'is_active': '1' + }, { 'id': '1141', 'option_group_id': '146', @@ -753,18 +765,6 @@ define([ 'is_reserved': '1', 'is_active': '1' }, - { - 'id': '1147', - 'option_group_id': '146', - 'label': '1 3/4 Days', - 'value': '1.75', - 'name': 'one_and_three_quarters_days', - 'is_default': '0', - 'weight': '8', - 'is_optgroup': '0', - 'is_reserved': '1', - 'is_active': '1' - }, { 'id': '1148', 'option_group_id': '146', @@ -826,24 +826,24 @@ define([ 'is_active': '1' } ], - hrjc_revision_change_reason: [{ - 'id': '938', - 'option_group_id': '110', - 'label': 'Promotion', + hrleaveandabsences_work_pattern_change_reason: [{ + 'id': '1314', + 'option_group_id': '196', + 'label': 'As per contract', 'value': '1', - 'name': 'Promotion', + 'name': 'as_per_contract', 'filter': '0', - 'is_default': '0', + 'is_default': '1', 'weight': '1', 'is_optgroup': '0', 'is_reserved': '0', 'is_active': '1' }, { - 'id': '939', - 'option_group_id': '110', - 'label': 'Increment', + 'id': '1315', + 'option_group_id': '196', + 'label': 'Change in contractual hours', 'value': '2', - 'name': 'Increment', + 'name': 'change_in_contractual_hours', 'filter': '0', 'is_default': '0', 'weight': '2', @@ -851,11 +851,11 @@ define([ 'is_reserved': '0', 'is_active': '1' }, { - 'id': '940', - 'option_group_id': '110', - 'label': 'Disciplinary', + 'id': '1316', + 'option_group_id': '196', + 'label': 'Change in contract type', 'value': '3', - 'name': 'Disciplinary', + 'name': 'change_in_contract_type', 'filter': '0', 'is_default': '0', 'weight': '3', diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/helpers/request-modal-helper.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/helpers/request-modal-helper.js index 78acc4eedec..717fbab1df6 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/helpers/request-modal-helper.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/mocks/helpers/request-modal-helper.js @@ -1,4 +1,4 @@ -/* eslint-env amd */ +/* eslint-env amd, jasmine */ define([ 'common/lodash', @@ -87,7 +87,7 @@ define([ }, /** - * sets from and/or to dates + * Sets "from" and/or "to" dates * * @param {object} controller controller object * @param {String} from date set if passed @@ -107,6 +107,27 @@ define([ controller.dateChangeHandler('to'); $rootScope.$digest(); } + }, + + /** + * Sets "from" and/or "to" times + * + * @param {Object} controller - controller object + * @param {String} from - time in HH:mm format, optional + * @param {String} to - time in HH:mm format, optional + */ + setTestTimes: function (controller, from, to) { + var $rootScope = getDependency('$rootScope'); + + if (from) { + controller.uiOptions.times.from.time = from; + $rootScope.$digest(); + } + + if (to) { + controller.uiOptions.times.to.time = to; + $rootScope.$digest(); + } } }; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-day.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-day.component.spec.js index 075da8cea8e..34e66b77bb4 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-day.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-day.component.spec.js @@ -12,17 +12,24 @@ define([ 'use strict'; describe('leaveCalendarDay', function () { - var $componentController, $log, $rootScope, absenceType, absenceTypes, + var $componentController, $log, $rootScope, $timeout, absenceType, absenceTypes, calculationUnits, calculationUnitInDays, calculationUnitInHours, - contactData, controller, dayTypes, LeavePopup, leaveRequest; + contactData, controller, dayTypes, LeavePopup, leaveRequest, leaveRequestAttributes; beforeEach(module('manager-leave')); - beforeEach(inject(function (_$componentController_, _$log_, _$rootScope_, _LeavePopup_) { + beforeEach(inject(function (_$componentController_, _$log_, _$rootScope_, _$timeout_, _LeavePopup_) { $componentController = _$componentController_; $log = _$log_; $rootScope = _$rootScope_; - absenceTypes = absenceTypeData.all().values; + $timeout = _$timeout_; + absenceTypes = _.cloneDeep(absenceTypeData.all().values); contactData = {}; + leaveRequest = _.cloneDeep(leaveRequestData.all().values[0]); + contactData.leaveRequests = [leaveRequest]; + contactData.leaveRequestsToShowInCell = [leaveRequest]; + contactData.leaveRequestsAttributes = {}; + contactData.leaveRequestsAttributes[leaveRequest.id] = {}; + leaveRequestAttributes = contactData.leaveRequestsAttributes[leaveRequest.id]; calculationUnits = optionGroupData.getCollection( 'hrleaveandabsences_absence_type_calculation_unit'); dayTypes = optionGroupData.getCollection( @@ -48,34 +55,30 @@ define([ }); describe('mapping leave request fields', function () { - var absenceType; - beforeEach(function () { compileComponent(); - leaveRequest = _.cloneDeep(leaveRequestData.all().values[0]); - contactData.leaveRequest = leaveRequest; absenceType = _.find(absenceTypes, function (type) { return +type.id === +leaveRequest.type_id; }); }); - describe('for any calculation unit', function () { + describe('basic tests', function () { beforeEach(function () { $rootScope.$digest(); }); - it('maps the absence type title', function () { - expect(leaveRequest['type_id.title']).toEqual(absenceType.title); + it('sets the absence type title', function () { + expect(leaveRequestAttributes['absenceTypeTitle']).toEqual(absenceType.title); }); it('sets dates ready for formatting', function () { - expect(controller.dates.from).toEqual(new Date(leaveRequest.from_date)); - expect(controller.dates.to).toEqual(new Date(leaveRequest.to_date)); + expect(leaveRequestAttributes.from_date).toEqual(new Date(leaveRequest.from_date)); + expect(leaveRequestAttributes.to_date).toEqual(new Date(leaveRequest.to_date)); }); it('sets the calculation unit', function () { - expect(controller.calculationUnit).toEqual(jasmine.any(Object)); + expect(leaveRequestAttributes.unit).toEqual(jasmine.any(String)); }); }); @@ -95,15 +98,15 @@ define([ }); it('sets the "days" calculation unit', function () { - expect(controller.calculationUnit.name).toEqual('days'); + expect(leaveRequestAttributes.unit).toEqual('days'); }); it('maps the from date type label', function () { - expect(leaveRequest['from_date_type.label']).toEqual(fromDateType.label); + expect(leaveRequestAttributes.from_date_type).toEqual(fromDateType.label); }); it('maps the to date type label', function () { - expect(leaveRequest['from_date_type.label']).toEqual(toDateType.label); + expect(leaveRequestAttributes.from_date_type).toEqual(toDateType.label); }); }); @@ -115,12 +118,12 @@ define([ }); it('sets the "hours" calculation unit', function () { - expect(controller.calculationUnit.name).toEqual('hours'); + expect(leaveRequestAttributes.unit).toEqual('hours'); }); it('does not map neither "from" nor "to" date type label', function () { - expect(leaveRequest['from_date_type.label']).not.toBeDefined(); - expect(leaveRequest['to_date_type.label']).not.toBeDefined(); + expect(leaveRequestAttributes.from_date_type).not.toBeDefined(); + expect(leaveRequestAttributes.to_date_type).not.toBeDefined(); }); }); }); @@ -137,47 +140,50 @@ define([ describe('Accrued TOIL', function () { beforeEach(function () { - contactData.isAccruedTOIL = true; + leaveRequestAttributes.isAccruedTOIL = true; + $rootScope.$digest(); }); it('sets day label equal to AT', function () { - expect(controller.label).toBe('AT'); + expect(leaveRequestAttributes.label).toBe('AT'); }); }); describe('half day AM', function () { beforeEach(function () { absenceType.calculation_unit = calculationUnitInDays; - contactData.isAM = true; + leaveRequestAttributes.isAM = true; $rootScope.$digest(); }); it('sets day label equal to AM', function () { - expect(controller.label).toBe('AM'); + expect(leaveRequestAttributes.label).toBe('AM'); }); }); describe('half day PM', function () { beforeEach(function () { absenceType.calculation_unit = calculationUnitInDays; - contactData.isPM = true; + leaveRequestAttributes.isPM = true; + $rootScope.$digest(); }); it('sets day label equal to PM', function () { - expect(controller.label).toBe('PM'); + expect(leaveRequestAttributes.label).toBe('PM'); }); }); describe('full day', function () { beforeEach(function () { absenceType.calculation_unit = calculationUnitInDays; + $rootScope.$digest(); }); it('sets day label equal to empty string', function () { - expect(controller.label).toBe(''); + expect(leaveRequestAttributes.label).toBe(''); }); }); @@ -188,11 +194,12 @@ define([ absenceType.calculation_unit = calculationUnitInHours; controller.date = leaveRequest.from_date; time = moment(leaveRequest.from_date).format('HH:mm'); + $rootScope.$digest(); }); it('sets day label equal the start time of the request', function () { - expect(controller.label).toBe(time); + expect(leaveRequestAttributes.label).toBe(time); }); }); @@ -203,11 +210,12 @@ define([ absenceType.calculation_unit = calculationUnitInHours; controller.date = leaveRequest.to_date; time = moment(leaveRequest.to_date).format('HH:mm'); + $rootScope.$digest(); }); it('sets day label equal the end time of the request', function () { - expect(controller.label).toBe(time); + expect(leaveRequestAttributes.label).toBe(time); }); }); @@ -218,110 +226,101 @@ define([ absenceType.calculation_unit = calculationUnitInHours; controller.date = startDate.add(1, 'days').format(dateFormat); - leaveRequest.to_date = startDate.add(2, 'days').format(dateFormat); + controller.contactData.leaveRequests[0].to_date = startDate.add(2, 'days').format(dateFormat); + $rootScope.$digest(); }); it('sets day label equal to empty string', function () { - expect(controller.label).toBe(''); + expect(leaveRequestAttributes.label).toBe(''); }); }); }); - describe('selecting a tooltip template', function () { - var nextWeek; + describe('openLeavePopup()', function () { + var event; + var leaveRequest = { key: 'value' }; + var leaveType = 'some_leave_type'; + var selectedContactId = '101'; + var isSelfRecord = true; beforeEach(function () { - nextWeek = moment(leaveRequest.from_date).add(7, 'days') - .format('YYYY-MM-DD HH:ii'); - contactData.leaveRequest = leaveRequest; + event = jasmine.createSpyObj('event', ['stopPropagation']); + spyOn(LeavePopup, 'openModal'); + controller.openLeavePopup(event, leaveRequest, leaveType, selectedContactId, isSelfRecord); }); - describe('when the request is for Accrued TOIL', function () { - beforeEach(function () { - controller.contactData.isAccruedTOIL = true; - - $rootScope.$digest(); - }); - - it('selects the tooltip template for accrued toil', function () { - expect(controller.tooltipTemplate).toBe('accrued-toil-tooltip'); - }); + it('opens the leave request popup', function () { + expect(LeavePopup.openModal).toHaveBeenCalledWith(leaveRequest, leaveType, selectedContactId, isSelfRecord); }); - describe('when the request is for a single day and the calculation unit is in hours', function () { - beforeEach(function () { - absenceType.calculation_unit = calculationUnitInHours; - leaveRequest.to_date = leaveRequest.from_date; - - $rootScope.$digest(); - }); + it('stops the event from propagating', function () { + expect(event.stopPropagation).toHaveBeenCalled(); + }); + }); - it('selects the tooltip template for unit type hours on single date', function () { - expect(controller.tooltipTemplate).toBe('type-hours-on-single-date-tooltip'); - }); + // @TODO this should be moved to a decorator to uib-tooltip + describe('toggleTooltip()', function () { + it('has the tooltip hidden by default', function () { + expect(controller.tooltip.show).toBe(false); }); - describe('when the request is for multiple days and the calculation unit is in hours', function () { + describe('when user hovers the day cell', function () { beforeEach(function () { - absenceType.calculation_unit = calculationUnitInHours; - leaveRequest.to_date = nextWeek; - - $rootScope.$digest(); + toggleTooltip('day_cell', true); }); - it('selects the tooltip template for unit type hours on multiple dates', function () { - expect(controller.tooltipTemplate).toBe('type-hours-on-multiple-dates-tooltip'); + it('shows tooltip', function () { + expect(controller.tooltip.show).toBe(true); }); - }); - - describe('when the request is for a single day and the calculation unit is in days', function () { - beforeEach(function () { - absenceType.calculation_unit = calculationUnitInDays; - leaveRequest.to_date = leaveRequest.from_date; - $rootScope.$digest(); - }); + describe('and then user unhovers the day cell', function () { + beforeEach(function () { + toggleTooltip('day_cell', false); + }); - it('selects the tooltip template for unit type days on single date', function () { - expect(controller.tooltipTemplate).toBe('type-days-on-single-date-tooltip'); + it('hides the tooltip', function () { + expect(controller.tooltip.show).toBe(false); + }); }); - }); - describe('when the request is for multiple days and the calculation unit is in days', function () { - beforeEach(function () { - absenceType.calculation_unit = calculationUnitInDays; - leaveRequest.to_date = nextWeek; + describe('and then user unhovers the day cell but hovers the tooltip', function () { + beforeEach(function () { + toggleTooltip('day_cell', false); + toggleTooltip('tooltip', true); + }); - $rootScope.$digest(); - }); + it('leaves the tooltip shown', function () { + expect(controller.tooltip.show).toBe(true); + }); - it('selects the tooltip template for unit type days on multiple dates', function () { - expect(controller.tooltipTemplate).toBe('type-days-on-multiple-dates-tooltip'); - }); - }); - }); + describe('and then user unhovers the tooltip', function () { + beforeEach(function () { + toggleTooltip('tooltip', false); + }); - describe('openLeavePopup()', function () { - var event; - var leaveRequest = { key: 'value' }; - var leaveType = 'some_leave_type'; - var selectedContactId = '101'; - var isSelfRecord = true; + it('hides the tooltip', function () { + expect(controller.tooltip.show).toBe(false); + }); + }); - beforeEach(function () { - event = jasmine.createSpyObj('event', ['stopPropagation']); - spyOn(LeavePopup, 'openModal'); - controller.openLeavePopup(event, leaveRequest, leaveType, selectedContactId, isSelfRecord); - }); + describe('and then user unhovers the tooltip but hovers the day cell back', function () { + beforeEach(function () { + toggleTooltip('tooltip', false); + toggleTooltip('tooltip', true); + }); - it('opens the leave request popup', function () { - expect(LeavePopup.openModal).toHaveBeenCalledWith(leaveRequest, leaveType, selectedContactId, isSelfRecord); + it('leaves the tooltip shown', function () { + expect(controller.tooltip.show).toBe(true); + }); + }); + }); }); - it('stops the event from propagating', function () { - expect(event.stopPropagation).toHaveBeenCalled(); - }); + function toggleTooltip (sourceElement, isHovered) { + controller.toggleTooltip(sourceElement, isHovered); + $timeout.flush(); + } }); /** diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-month.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-month.component.spec.js index 23e97c71916..68cfd525b48 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-month.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-calendar-month.component.spec.js @@ -23,7 +23,7 @@ describe('leaveCalendarMonth', function () { var $componentController, $log, $provide, $q, $rootScope, Calendar, LeaveRequest, OptionGroup, controller, daysInFebruary, february, leaveRequestInFebruary, - period2016, publicHolidays, pubSub; + period2016, publicHolidays, pubSub, contactData, leaveRequest, leaveRequestAttributes; var currentContactId = CRM.vars.leaveAndAbsences.contactId; var contactIdsToReduceTo = null; @@ -388,6 +388,11 @@ jasmine.clock().uninstall(); }); + /** + * Mocks current day + * + * @param {String} date + */ function setCurrentDay (date) { jasmine.clock().mockDate(date); compileComponent(); @@ -396,8 +401,6 @@ }); describe("day's data specific for each contact", function () { - var contactData; - beforeEach(function () { sendShowMonthsSignal(); }); @@ -447,8 +450,84 @@ }); }); + describe('when the contact has multiple leave requests on the same day', function () { + var leaveRequest1, leaveRequest2; + + describe('basic tests', function () { + beforeEach(function () { + leaveRequest1 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest2 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + + commonSetup([leaveRequest1, leaveRequest2]); + }); + + it('has leave requests references in the contact data', function () { + expect(contactData.leaveRequests.length).toBe(2); + expect(contactData.leaveRequests[0]).toBe(leaveRequest1); + expect(contactData.leaveRequests[1]).toBe(leaveRequest2); + }); + + it('keeps references to leave requests to show in day cell', function () { + expect(contactData.leaveRequestsToShowInCell.length).toBe(2); + expect(contactData.leaveRequestsToShowInCell[0]).toBe(leaveRequest1); + expect(contactData.leaveRequestsToShowInCell[1]).toBe(leaveRequest2); + }); + }); + + describe('when day contains unsorted requests in hours', function () { + beforeEach(function () { + leaveRequest1 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest1.from_date = leaveRequest1.from_date.split(' ')[0] + ' 23:00'; + leaveRequest2 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest2.from_date = leaveRequest2.from_date.split(' ')[0] + ' 11:00'; + + commonSetup([leaveRequest1, leaveRequest2]); + }); + + it('sorts leave requests', function () { + expect(contactData.leaveRequests[0]).toBe(leaveRequest2); + expect(contactData.leaveRequests[1]).toBe(leaveRequest1); + }); + }); + + describe('when day contains unsorted requests in days', function () { + beforeEach(function () { + leaveRequest1 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest1.from_date_type = getDayTypeId('half_day_pm'); + leaveRequest2 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest2.from_date_type = getDayTypeId('half_day_am'); + + commonSetup([leaveRequest1, leaveRequest2]); + }); + + it('sorts leave requests', function () { + expect(contactData.leaveRequests[0]).toBe(leaveRequest2); + expect(contactData.leaveRequests[1]).toBe(leaveRequest1); + }); + }); + + describe('when day contains a mix of TOIL and non-TOIL requests', function () { + beforeEach(function () { + leaveRequest1 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest2 = _.clone(LeaveRequestData.singleDataSuccess().values[0]); + leaveRequest2.request_type = 'toil'; + + commonSetup([leaveRequest1, leaveRequest2]); + }); + + it('only shows toil requests in the day cell', function () { + expect(contactData.leaveRequestsToShowInCell.length).toBe(1); + expect(contactData.leaveRequestsToShowInCell[0]).toBe(leaveRequest2); + }); + + it('still has all leave request references', function () { + expect(contactData.leaveRequests.length).toBe(2); + }); + }); + }); + describe('when the contact has recorded a leave request on the day', function () { - var leaveRequest, workPattern; + var workPattern; beforeEach(function () { leaveRequest = _.clone(LeaveRequestData.singleDataSuccess().values[0]); @@ -465,11 +544,15 @@ 'hrleaveandabsences_leave_request_status', 'name', 'approved' ).value; - contactData = commonSetup(); + commonSetup(); }); it('contains a reference to the leave request itself', function () { - expect(contactData.leaveRequest).toBe(leaveRequest); + expect(contactData.leaveRequests[0]).toBe(leaveRequest); + }); + + it('adds a reference to the leave request to show it in the day cell', function () { + expect(contactData.leaveRequestsToShowInCell[0]).toBe(leaveRequest); }); it('assigns it the colors of its absence type', function () { @@ -477,7 +560,7 @@ return absenceType.id === leaveRequest.type_id; }).color; - expect(contactData.styles).toEqual({ + expect(leaveRequestAttributes.styles).toEqual({ backgroundColor: absenceTypeColor, borderColor: absenceTypeColor }); @@ -490,39 +573,35 @@ 'hrleaveandabsences_leave_request_status', 'name', 'awaiting_approval' ).value; - contactData = commonSetup(); + commonSetup(); }); it('marks it as such', function () { - expect(contactData.isRequested).toBe(true); + expect(leaveRequestAttributes.isRequested).toBe(true); }); }); describe('when the leave request is for half day am', function () { beforeEach(function () { - leaveRequest.from_date_type = _.find(OptionGroupData.getCollection('hrleaveandabsences_leave_request_day_type'), function (absenceType) { - return absenceType.name === 'half_day_am'; - }).value; + leaveRequest.from_date_type = getDayTypeId('half_day_am'); - contactData = commonSetup(); + commonSetup(); }); it('marks it as such', function () { - expect(contactData.isAM).toBe(true); + expect(leaveRequestAttributes.isAM).toBe(true); }); }); describe('when leave request is for half day pm', function () { beforeEach(function () { - leaveRequest.from_date_type = _.find(OptionGroupData.getCollection('hrleaveandabsences_leave_request_day_type'), function (absenceType) { - return absenceType.name === 'half_day_pm'; - }).value; + leaveRequest.from_date_type = getDayTypeId('half_day_pm'); - contactData = commonSetup(); + commonSetup(); }); it('marks it as such', function () { - expect(contactData.isPM).toBe(true); + expect(leaveRequestAttributes.isPM).toBe(true); }); }); @@ -530,33 +609,34 @@ beforeEach(function () { leaveRequest.request_type = 'toil'; - contactData = commonSetup(); + commonSetup(); }); it('marks it as such', function () { - expect(contactData.isAccruedTOIL).toBe(true); + expect(leaveRequestAttributes.isAccruedTOIL).toBe(true); }); }); - function commonSetup () { - var day; + describe('when the leave request is a single day request', function () { + beforeEach(function () { + leaveRequest.from_date = leaveRequest.to_date; - LeaveRequest.all.and.callFake(function () { - return $q.resolve({ list: [leaveRequest] }); + commonSetup(); }); - compileComponent(true); - - controller.month.days.forEach(function (dayObj) { - if (moment(dayObj.date).isSame(leaveRequest.from_date, 'day')) { - day = dayObj; - } + it('marks it as such', function () { + expect(leaveRequestAttributes.isSingleDay).toBe(true); }); - - return day.contactsData[currentContactId]; - } + }); }); + /** + * Returns a day by a given day type + * + * @param {String} dayType + * @param {Boolean} returnContactData + * @return {Object} + */ function getDayWithType (dayType, returnContactData) { var day; @@ -595,9 +675,13 @@ describe('leave request status update event', function () { beforeEach(function () { + var shrinkedLeaveRequest = _.cloneDeep(leaveRequestToDelete); + // Srinking the leave in terms of dates to ensure later that all dates are flushed + shrinkedLeaveRequest.to_date = shrinkedLeaveRequest.from_date; + pubSub.publish('LeaveRequest::statusUpdate', { status: 'delete', - leaveRequest: leaveRequestToDelete + leaveRequest: shrinkedLeaveRequest }); $rootScope.$digest(); }); @@ -605,12 +689,15 @@ itHandlesLeaveRequestDeleteEvent(); }); + /** + * Checks that the leave request is deleted + */ function itHandlesLeaveRequestDeleteEvent () { it('does not re-fetch the leave requests from the backend', function () { expect(LeaveRequest.all).not.toHaveBeenCalled(); }); - it('resets the properties of each day that the leave request spans', function () { + it('resets the properties of each day that the original leave request spans', function () { expect(getLeaveRequestDays(leaveRequestToDelete).every(isDayContactDataNull)).toBe(true); }); } @@ -638,28 +725,37 @@ }); describe('when a leave request is updated and its dates have changed', function () { - var leaveRequestToUpdate, oldDays, newDays; + var leaveRequestToUpdate; beforeEach(function () { leaveRequestToUpdate = _.clone(leaveRequestInFebruary); - oldDays = getLeaveRequestDays(leaveRequestToUpdate); leaveRequestToUpdate = modifyLeaveRequestData(leaveRequestToUpdate); LeaveRequest.all.calls.reset(); }); describe('leave request edit event', function () { + var updatedRequest; + beforeEach(function () { pubSub.publish('LeaveRequest::edit', leaveRequestToUpdate); $rootScope.$digest(); - newDays = getLeaveRequestDays(leaveRequestToUpdate); + updatedRequest = _.find(controller.month.days, function (day) { + return _.find(day.contactsData[leaveRequestToUpdate.contact_id].leaveRequests, function (leaveRequest) { + return leaveRequest === leaveRequestToUpdate; + }); + }); }); - itHandlesLeaveRequestStatusUpdate(); + it('updates the leaveRequest', function () { + expect(updatedRequest).toBeDefined(); + }); }); describe('leave request status update event', function () { + var updatedRequest; + beforeEach(function () { pubSub.publish('LeaveRequest::statusUpdate', { status: 'cancel', @@ -667,27 +763,28 @@ }); $rootScope.$digest(); - newDays = getLeaveRequestDays(leaveRequestToUpdate); - }); - }); - - function itHandlesLeaveRequestStatusUpdate () { - it('does not re-fetch the leave requests from the backend', function () { - expect(LeaveRequest.all).not.toHaveBeenCalled(); - }); - - it('resets the properties of the days that the leave request does not span anymore', function () { - expect(oldDays.every(isDayContactDataNull)).toBe(true); + updatedRequest = _.find(controller.month.days, function (day) { + return _.find(day.contactsData[leaveRequestToUpdate.contact_id].leaveRequests, function (leaveRequest) { + return leaveRequest === leaveRequestToUpdate; + }); + }); }); - it('sets the properties of the days that the leave request now spans', function () { - expect(newDays.every(isDayContactDataNull)).toBe(false); + it('updates the leaveRequest', function () { + expect(updatedRequest).toBeDefined(); }); - } + }); }); + /** + * Modifies leave request by settings different dates + * + * @param {LeaveRequestInstance} leaveRequest + * @param {Boolean} modifyId if to modify id or not + * @return {LeaveRequestInstance} + */ function modifyLeaveRequestData (leaveRequest, modifyId) { - var modified = _.assign({}, leaveRequest, { + var modifiedLeaveRequest = _.assign({}, leaveRequest, { from_date: '2016-02-20', to_date: '2016-02-21', dates: [ @@ -696,13 +793,19 @@ ] }); - if (modifyId === true) { - modified.id = '1'; + if (modifyId) { + modifiedLeaveRequest.id = '1'; } - return modified; + return modifiedLeaveRequest; } + /** + * Returns the array of days for the leave request + * + * @param {LeaveRequestInstance} leaveRequest + * @return {Array} + */ function getLeaveRequestDays (leaveRequest) { var days = []; var pointerDate = moment(leaveRequest.from_date).clone(); @@ -719,15 +822,17 @@ return days; } + /** + * Checks if day contact data is empty + * + * @param {Object} day + * @return {Boolean} + */ function isDayContactDataNull (day) { - var contactData = day.contactsData[currentContactId]; - - return contactData.leaveRequest === null && - contactData.styles === null && - contactData.isAccruedTOIL === null && - contactData.isRequested === null && - contactData.isAM === null && - contactData.isPM === null; + var leaveRequests = day.contactsData[currentContactId].leaveRequests; + var leaveRequestsAttributes = day.contactsData[currentContactId].leaveRequestsAttributes; + + return !leaveRequests.length && !Object.keys(leaveRequestsAttributes).length; } }); @@ -803,6 +908,38 @@ }); }); + /** + * Initializes controller with default or given leave requests + * and caches day, contact data and leave request attributes + * for the first leave request in the list for testing convenience + * + * @param {Array} leaveRequests - optional array of {LeaveRequestInstance} + */ + function commonSetup (leaveRequests) { + var day; + var leaveRequestsToUse = leaveRequests || [leaveRequest]; + + LeaveRequest.all.and.callFake(function () { + return $q.resolve({ list: leaveRequestsToUse }); + }); + + compileComponent(true); + + controller.month.days.forEach(function (dayObj) { + if (moment(dayObj.date).isSame(leaveRequestsToUse[0].from_date, 'day')) { + day = dayObj; + } + }); + + contactData = day.contactsData[currentContactId]; + leaveRequestAttributes = contactData.leaveRequestsAttributes[leaveRequestsToUse[0].id]; + } + + /** + * Compiles component + * + * @param {Boolean} sendSignal - if to send a month signal or not + */ function compileComponent (sendSignal) { controller = $componentController('leaveCalendarMonth', null, { contacts: ContactData.all.values, @@ -820,6 +957,19 @@ !!sendSignal && sendShowMonthsSignal(); } + /** + * Gets day type ID by its name + * + * @param {String} dayTypeName + * @return {String} + */ + function getDayTypeId (dayTypeName) { + return _.find(OptionGroupData.getCollection( + 'hrleaveandabsences_leave_request_day_type'), function (dayType) { + return dayType.name === dayTypeName; + }).value; + } + /** * Sends the "show months" signal to the component * diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-actions.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-actions.component.spec.js index 8c5c1111e25..248c2a17f1c 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-actions.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-actions.component.spec.js @@ -192,8 +192,8 @@ define([ compileComponent(); }); - it('shows actions "View"', function () { - expect(flattenActions(controller.allowedActions)).toEqual(['view']); + it('shows actions "View" and "Cancel"', function () { + expect(flattenActions(controller.allowedActions)).toEqual(['view', 'cancel']); }); }); }); @@ -234,8 +234,8 @@ define([ compileComponent(); }); - it('shows actions "View"', function () { - expect(flattenActions(controller.allowedActions)).toEqual(['view']); + it('shows actions "View" and "Cancel"', function () { + expect(flattenActions(controller.allowedActions)).toEqual(['view', 'cancel']); }); }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-popup-details-tab.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-popup-details-tab.component.spec.js index 1634a170c64..dd70fdae580 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-popup-details-tab.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-popup-details-tab.component.spec.js @@ -22,7 +22,7 @@ define([ describe('leaveRequestPopupDetailsTab', function () { var $componentController, $controllerProvider, $provide, $q, $log, $rootScope, $scope, controller, - sharedSettings, LeaveRequestAPI, AbsenceType, AbsenceTypeAPI, LeaveRequestInstance, + sharedSettings, LeaveRequestAPI, AbsenceType, AbsenceTypeAPI, LeaveRequest, LeaveRequestInstance, OptionGroup, OptionGroupAPIMock, selectedAbsenceType, WorkPatternAPI, EntitlementAPI; var date2013 = '02/02/2013'; @@ -53,14 +53,15 @@ define([ }])); beforeEach(inject(function ( - _$componentController_, _$q_, _$log_, _$rootScope_, _AbsenceType_, _AbsenceTypeAPI_, _LeaveRequestInstance_, - _OptionGroup_, _OptionGroupAPIMock_, _LeaveRequestAPI_, _WorkPatternAPI_, _EntitlementAPI_) { + _$componentController_, _$q_, _$log_, _$rootScope_, _AbsenceType_, _AbsenceTypeAPI_, _LeaveRequest_, + _LeaveRequestInstance_, _OptionGroup_, _OptionGroupAPIMock_, _LeaveRequestAPI_, _WorkPatternAPI_, _EntitlementAPI_) { $componentController = _$componentController_; $log = _$log_; $q = _$q_; $rootScope = _$rootScope_; AbsenceType = _AbsenceType_; AbsenceTypeAPI = _AbsenceTypeAPI_; + LeaveRequest = _LeaveRequest_; LeaveRequestInstance = _LeaveRequestInstance_; LeaveRequestAPI = _LeaveRequestAPI_; WorkPatternAPI = _WorkPatternAPI_; @@ -215,7 +216,9 @@ define([ beforeEach(function () { controller.period = {}; + togglePublicHolidayRequestForCurrentDate(false); requestModalHelper.setTestDates(controller, date2016); + fromDate = moment(controller.uiOptions.fromDate).format(sharedSettings.serverDateFormat); }); @@ -293,13 +296,26 @@ define([ expect(controller.requestFromDayTypes.length).toEqual(3); }); }); + + describe('and from date is a public holiday', function () { + beforeEach(function () { + togglePublicHolidayRequestForCurrentDate(true); + requestModalHelper.setTestDates(controller, date2016); + }); + + it('sets public_holiday day type', function () { + expect(controller.requestFromDayTypes[0].label).toEqual('Public Holiday'); + }); + }); }); describe('after to date is selected', function () { var toDate; beforeEach(function () { + togglePublicHolidayRequestForCurrentDate(false); requestModalHelper.setTestDates(controller, date2016, date2016To); + toDate = moment(controller.uiOptions.toDate).format(sharedSettings.serverDateFormat); }); @@ -434,6 +450,8 @@ define([ beforeEach(function () { expectedDayType = optionGroupMock.specificValue('hrleaveandabsences_leave_request_day_type', 'value', '1'); + + togglePublicHolidayRequestForCurrentDate(false); requestModalHelper.setTestDates(controller, null, date2016); }); @@ -560,6 +578,20 @@ define([ expect(controller.uiOptions.multipleDays).toBeFalsy(); }); + describe('after changed to multiple days mode', function () { + beforeEach(function () { + controller.uiOptions.multipleDays = true; + + controller.daysSelectionModeChangeHandler(); + $rootScope.$digest(); + }); + + it('shows both "from" and "to" times', function () { + expect(controller.uiOptions.times.from.loading).toBe(false); + expect(controller.uiOptions.times.to.loading).toBe(false); + }); + }); + describe('after from date is selected', function () { var timeFromObject, request, workDayMock; @@ -1254,9 +1286,9 @@ define([ expect(controller.request.contact_id).toEqual(CRM.vars.leaveAndAbsences.contactId.toString()); expect(controller.request.type_id).toEqual(leaveRequestAttributes.type_id); expect(controller.request.status_id).toEqual(waitingApprovalStatus.value); - expect(controller.request.from_date).toEqual(leaveRequestAttributes.from_date); + expect(controller.request.from_date).toEqual(moment(leaveRequestAttributes.from_date).format('YYYY-MM-DD')); expect(controller.request.from_date_type).toEqual(leaveRequestAttributes.from_date_type); - expect(controller.request.to_date).toEqual(leaveRequestAttributes.to_date); + expect(controller.request.to_date).toEqual(moment(leaveRequestAttributes.to_date).format('YYYY-MM-DD')); expect(controller.request.to_date_type).toEqual(leaveRequestAttributes.to_date_type); }); @@ -1673,5 +1705,26 @@ define([ return moment.duration(timeTo) .subtract(moment.duration(timeFrom)).asHours().toString(); } + + /** + * Toggles whether there is a "public_holiday" leave request + * for the current date (for the purpose of the test it doesn't matter if + * the current date is the "from" or "to" date) + * + * @param {Boolean} addPublicHolidayRequest + */ + function togglePublicHolidayRequestForCurrentDate (addPublicHolidayRequest) { + var spy; + + if (typeof LeaveRequest.all.calls !== 'undefined') { + spy = LeaveRequest.all; + } else { + spy = spyOn(LeaveRequest, 'all'); + } + + spy.and.returnValue($q.resolve({ + list: addPublicHolidayRequest ? [jasmine.any(Object)] : [] + })); + } }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-record-actions.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-record-actions.component.spec.js index 74cb56f24ca..7888174f7bb 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-record-actions.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/leave-request-record-actions.component.spec.js @@ -37,7 +37,7 @@ define([ return option.type; }); - expect(options).toEqual(['leave', 'sickness', 'toil']); + expect(options).toEqual(['leave', 'sickness']); }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/staff-leave-report.component.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/staff-leave-report.component.spec.js index 7b22aca183c..50189afe2e0 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/staff-leave-report.component.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/components/staff-leave-report.component.spec.js @@ -772,23 +772,33 @@ }); describe('when the leave request was already approved', function () { - var oldRemainder, newRemainder; + var oldRemainders, newRemainders; beforeEach(function () { controller.sections.approved.data = [leaveRequest1, leaveRequest2, leaveRequest3]; controller.sections.approved.dataIndex = _.indexBy(controller.sections.approved.data, 'id'); - oldRemainder = controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.current; + + oldRemainders = { + current: controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.current, + future: controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.future + }; leaveRequest1.delete(); pubSub.publish('LeaveRequest::delete', leaveRequest1); $rootScope.$digest(); - newRemainder = controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.current; + newRemainders = { + current: controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.current, + future: controller.absenceTypesIndexed[leaveRequest1.type_id].remainder.future + }; }); - it('updates the current remainder of the entitlement of the absence type the leave request was for', function () { - expect(newRemainder).not.toBe(oldRemainder); - expect(newRemainder).toBe(oldRemainder - leaveRequest1.balance_change); + it('updates both the current and future remainders of the entitlement of the absence type the leave request was for', function () { + expect(newRemainders.current).not.toBe(oldRemainders.current); + expect(newRemainders.future).not.toBe(oldRemainders.future); + + expect(newRemainders.current).toBe(oldRemainders.current - leaveRequest1.balance_change); + expect(newRemainders.future).toBe(oldRemainders.future - leaveRequest1.balance_change); }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/request.controller.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/request.controller.spec.js index e22643da8f4..671dff7d386 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/request.controller.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/request.controller.spec.js @@ -593,261 +593,285 @@ }); describe('manager opens leave request popup in edit mode', function () { - beforeEach(function () { - var status = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '3'); - var leaveRequest = LeaveRequestInstance.init(mockData.findBy('status_id', status)); - - leaveRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); - role = 'manager'; - - initTestController({ leaveRequest: leaveRequest }); - }); - - describe('on initialization', function () { - var waitingApprovalStatus; - + describe('when leave request "from" date is same as absence period start date *or* "to" date is same as absence period end date', function () { beforeEach(function () { - waitingApprovalStatus = optionGroupMock.specificObject('hrleaveandabsences_leave_request_status', 'value', '3'); - }); - - it('sets the manager role', function () { - expect(controller.isRole('manager')).toBeTruthy(); - }); - - it('sets all leaverequest values', function () { - expect(controller.request.contact_id).toEqual('' + CRM.vars.leaveAndAbsences.contactId); - expect(controller.request.type_id).toEqual(jasmine.any(String)); - expect(controller.request.status_id).toEqual(waitingApprovalStatus.value); - expect(controller.request.from_date).toEqual(jasmine.any(String)); - expect(controller.request.from_date_type).toEqual(jasmine.any(String)); - expect(controller.request.to_date).toEqual(jasmine.any(String)); - expect(controller.request.to_date_type).toEqual(jasmine.any(String)); - }); + var status = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '3'); + var leaveRequest = LeaveRequestInstance.init(mockData.findBy('status_id', status)); - it('gets contact name', function () { - expect(controller.contactName).toEqual(jasmine.any(String)); - }); + leaveRequest.from_date = '2017-12-31 00:00:00'; + leaveRequest.to_date = '2017-12-31 23:59:00'; + leaveRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); + role = 'manager'; - it('does not allow user to submit', function () { - expect(controller.canSubmit()).toBeFalsy(); + initTestController({ leaveRequest: leaveRequest }); + spyOn(controller.request, 'update').and.callThrough(); + spyOn(LeaveRequestInstance, 'calculateBalanceChange').and.returnValue( + $q.resolve({ amount: controller.balance.change.amount })); + $rootScope.$digest(); }); - it('does not allow to change absence type', function () { - expect(controller.canChangeAbsenceType()).toBeFalsy(); + it('matches leave request with according absence period', function () { + expect(controller.period).toBeDefined(); }); }); - describe('on submit', function () { - var calculatedBalanceChangeAmount; - + describe('basic tests for when manager opens leave request popup in edit mode', function () { beforeEach(function () { - controller.balance.change.amount = controller.request.balance_change; - calculatedBalanceChangeAmount = controller.balance.change.amount; + var status = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '3'); + var leaveRequest = LeaveRequestInstance.init(mockData.findBy('status_id', status)); - spyOn($rootScope, '$emit'); - spyOn(controller.request, 'update').and.callThrough(); - // Pretending original balance change has not been updated - spyOn(LeaveRequestInstance, 'calculateBalanceChange').and.returnValue( - $q.resolve({ amount: calculatedBalanceChangeAmount })); + leaveRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); + role = 'manager'; - // entitlements are randomly generated so resetting them to positive here - if (controller.balance.closing < 0) { - controller.balance.closing = 0; - } - // set status id manually as manager would set it on UI - controller.newStatusOnSave = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '1'); + initTestController({ leaveRequest: leaveRequest }); }); - describe('if balance change has not been updated', function () { + describe('on initialization', function () { + var waitingApprovalStatus; + beforeEach(function () { - spyOn(controller.request, - 'checkIfBalanceChangeNeedsRecalculation') - .and.returnValue($q.resolve(false)); - controller.submit(); - $scope.$digest(); + waitingApprovalStatus = optionGroupMock.specificObject('hrleaveandabsences_leave_request_status', 'value', '3'); }); - it('allows user to submit', function () { - expect(controller.canSubmit()).toBeTruthy(); + it('sets the manager role', function () { + expect(controller.isRole('manager')).toBeTruthy(); }); - it('forces balance change to be recalculated', function () { - expect(controller.request.change_balance).toBeTruthy(); + it('sets all leaverequest values', function () { + expect(controller.request.contact_id).toEqual('' + CRM.vars.leaveAndAbsences.contactId); + expect(controller.request.type_id).toEqual(jasmine.any(String)); + expect(controller.request.status_id).toEqual(waitingApprovalStatus.value); + expect(controller.request.from_date).toEqual(jasmine.any(String)); + expect(controller.request.from_date_type).toEqual(jasmine.any(String)); + expect(controller.request.to_date).toEqual(jasmine.any(String)); + expect(controller.request.to_date_type).toEqual(jasmine.any(String)); }); - it('calls update method on instance', function () { - expect(controller.request.update).toHaveBeenCalled(); + it('gets contact name', function () { + expect(controller.contactName).toEqual(jasmine.any(String)); }); - it('calls corresponding API end points', function () { - expect(LeaveRequestAPI.isValid).toHaveBeenCalled(); - expect(LeaveRequestAPI.update).toHaveBeenCalled(); + it('does not allow user to submit', function () { + expect(controller.canSubmit()).toBeFalsy(); }); - it('sends update event', function () { - expect(pubSub.publish).toHaveBeenCalledWith('LeaveRequest::updatedByManager', controller.request); + it('does not allow to change absence type', function () { + expect(controller.canChangeAbsenceType()).toBeFalsy(); }); }); - describe('if balance change has been updated', function () { - var proceedWithBalanceChangeRecalculation; + describe('on submit', function () { + var calculatedBalanceChangeAmount; beforeEach(function () { - // Make original balance differ from the calculated balance - controller.balance.change.amount--; - - spyOn(controller.request, - 'checkIfBalanceChangeNeedsRecalculation') - .and.returnValue($q.resolve(true)); - spyOn(LeaveRequestService, - 'promptBalanceChangeRecalculation') - .and.callThrough(); - spyOn(dialog, 'open').and.callFake(function (params) { - proceedWithBalanceChangeRecalculation = params.onConfirm; - }); + controller.balance.change.amount = controller.request.balance_change; + calculatedBalanceChangeAmount = controller.balance.change.amount; + + spyOn($rootScope, '$emit'); + spyOn(controller.request, 'update').and.callThrough(); + // Pretending original balance change has not been updated + spyOn(LeaveRequestInstance, 'calculateBalanceChange').and.returnValue( + $q.resolve({ amount: calculatedBalanceChangeAmount })); + + // entitlements are randomly generated so resetting them to positive here + if (controller.balance.closing < 0) { + controller.balance.closing = 0; + } + // set status id manually as manager would set it on UI + controller.newStatusOnSave = optionGroupMock.specificValue('hrleaveandabsences_leave_request_status', 'value', '1'); }); - describe('basic tests', function () { + describe('if balance change has not been updated', function () { beforeEach(function () { + spyOn(controller.request, + 'checkIfBalanceChangeNeedsRecalculation') + .and.returnValue($q.resolve(false)); controller.submit(); - $rootScope.$digest(); + $scope.$digest(); + }); + + it('allows user to submit', function () { + expect(controller.canSubmit()).toBeTruthy(); + }); + + it('forces balance change to be recalculated', function () { + expect(controller.request.change_balance).toBeTruthy(); }); - it('does not call update method on instance', function () { - expect(controller.request.update).not.toHaveBeenCalled(); + it('calls update method on instance', function () { + expect(controller.request.update).toHaveBeenCalled(); }); - it('prompts a balance change recalculation', function () { - expect(LeaveRequestService.promptBalanceChangeRecalculation) - .toHaveBeenCalled(); + it('calls corresponding API end points', function () { + expect(LeaveRequestAPI.isValid).toHaveBeenCalled(); + expect(LeaveRequestAPI.update).toHaveBeenCalled(); }); - describe('when confirming balance change recalculation', function () { + it('sends update event', function () { + expect(pubSub.publish).toHaveBeenCalledWith('LeaveRequest::updatedByManager', controller.request); + }); + }); + + describe('if balance change has been updated', function () { + var proceedWithBalanceChangeRecalculation; + + beforeEach(function () { + // Make original balance differ from the calculated balance + controller.balance.change.amount--; + + spyOn(controller.request, + 'checkIfBalanceChangeNeedsRecalculation') + .and.returnValue($q.resolve(true)); + spyOn(LeaveRequestService, + 'promptBalanceChangeRecalculation') + .and.callThrough(); + spyOn(dialog, 'open').and.callFake(function (params) { + proceedWithBalanceChangeRecalculation = params.onConfirm; + }); + }); + + describe('basic tests', function () { beforeEach(function () { - proceedWithBalanceChangeRecalculation(); + controller.submit(); $rootScope.$digest(); }); - it('initiates the balance change recalculation', function () { - expect($rootScope.$emit).toHaveBeenCalledWith( - 'LeaveRequestPopup::recalculateBalanceChange'); + it('does not call update method on instance', function () { + expect(controller.request.update).not.toHaveBeenCalled(); + }); + + it('prompts a balance change recalculation', function () { + expect(LeaveRequestService.promptBalanceChangeRecalculation) + .toHaveBeenCalled(); }); - describe('after recalculation on submit attempt', function () { + describe('when confirming balance change recalculation', function () { beforeEach(function () { - controller.balance.change.amount = calculatedBalanceChangeAmount; - controller.submit(); + proceedWithBalanceChangeRecalculation(); $rootScope.$digest(); }); - it('updates leave request', function () { - expect(controller.request.update).toHaveBeenCalled(); + it('initiates the balance change recalculation', function () { + expect($rootScope.$emit).toHaveBeenCalledWith( + 'LeaveRequestPopup::recalculateBalanceChange'); + }); + + describe('after recalculation on submit attempt', function () { + beforeEach(function () { + controller.balance.change.amount = calculatedBalanceChangeAmount; + controller.submit(); + $rootScope.$digest(); + }); + + it('updates leave request', function () { + expect(controller.request.update).toHaveBeenCalled(); + }); }); }); }); - }); - describe('when cancelling request', function () { - var requestOriginalDates = {}; + describe('when cancelling request', function () { + var requestOriginalDates = {}; - beforeEach(function () { - requestOriginalDates.from = controller.request.from_date; - requestOriginalDates.to = controller.request.to_date; - controller.newStatusOnSave = optionGroupMock.specificObject( - 'hrleaveandabsences_leave_request_status', 'name', 'cancelled').value; + beforeEach(function () { + requestOriginalDates.from = controller.request.from_date; + requestOriginalDates.to = controller.request.to_date; + controller.newStatusOnSave = optionGroupMock.specificObject( + 'hrleaveandabsences_leave_request_status', 'name', 'cancelled').value; - controller.submit(); - $rootScope.$digest(); - }); + controller.submit(); + $rootScope.$digest(); + }); - it('does not check the balance change', function () { - expect(LeaveRequestService.promptBalanceChangeRecalculation) - .not.toHaveBeenCalled(); - }); + it('does not check the balance change', function () { + expect(LeaveRequestService.promptBalanceChangeRecalculation) + .not.toHaveBeenCalled(); + }); - it('updates request', function () { - expect(controller.request.update).toHaveBeenCalled(); - }); + it('updates request', function () { + expect(controller.request.update).toHaveBeenCalled(); + }); - it('tells the backend to not recalculate balance change', function () { - expect(controller.request.change_balance).toBeUndefined(); + it('tells the backend to not recalculate balance change', function () { + expect(controller.request.change_balance).toBeUndefined(); + }); + + it('reverts original request times', function () { + expect(moment(controller.request.from_date).format('HH:mm')).toEqual( + moment(requestOriginalDates.from).format('HH:mm')); + expect(moment(controller.request.to_date).format('HH:mm')).toEqual( + moment(requestOriginalDates.to).format('HH:mm')); + }); }); - it('reverts original request times', function () { - expect(moment(controller.request.from_date).format('HH:mm')).toEqual( - moment(requestOriginalDates.from).format('HH:mm')); - expect(moment(controller.request.to_date).format('HH:mm')).toEqual( - moment(requestOriginalDates.to).format('HH:mm')); + describe('when rejecting request', function () { + var requestOriginalDates = {}; + + beforeEach(function () { + requestOriginalDates.from = controller.request.from_date; + requestOriginalDates.to = controller.request.to_date; + controller.newStatusOnSave = optionGroupMock.specificObject( + 'hrleaveandabsences_leave_request_status', 'name', 'rejected').value; + // testing if time has been adjusted in UI, for example, due to work pattern change + controller.request.from_date = controller.request.from_date.split(' ')[0] + ' 01:01'; + controller.request.to_date = controller.request.to_date.split(' ')[0] + ' 01:02'; + + controller.submit(); + $rootScope.$digest(); + }); + + it('does not check the balance change', function () { + expect(LeaveRequestService.promptBalanceChangeRecalculation) + .not.toHaveBeenCalled(); + }); + + it('updates request', function () { + expect(controller.request.update).toHaveBeenCalled(); + }); + + it('tells the backend to not recalculate balance change', function () { + expect(controller.request.change_balance).toBeUndefined(); + }); + + it('reverts original request times', function () { + expect(moment(controller.request.from_date).format('HH:mm')).toEqual( + moment(requestOriginalDates.from).format('HH:mm')); + expect(moment(controller.request.to_date).format('HH:mm')).toEqual( + moment(requestOriginalDates.to).format('HH:mm')); + }); }); }); - describe('when rejecting request', function () { - var requestOriginalDates = {}; - + describe('in case leave request is TOIL', function () { beforeEach(function () { - requestOriginalDates.from = controller.request.from_date; - requestOriginalDates.to = controller.request.to_date; - controller.newStatusOnSave = optionGroupMock.specificObject( - 'hrleaveandabsences_leave_request_status', 'name', 'rejected').value; - // testing if time has been adjusted in UI, for example, due to work pattern change - controller.request.from_date = controller.request.from_date.split(' ')[0] + ' 01:01'; - controller.request.to_date = controller.request.to_date.split(' ')[0] + ' 01:02'; + controller.request.request_type = 'toil'; + controller.balance.change.amount--; controller.submit(); - $rootScope.$digest(); + spyOn(dialog, 'open'); + $rootScope.$apply(); }); - it('does not check the balance change', function () { - expect(LeaveRequestService.promptBalanceChangeRecalculation) - .not.toHaveBeenCalled(); + it('ignores balance changes and does not open confirmation dialog', function () { + expect(dialog.open).not.toHaveBeenCalled(); }); - it('updates request', function () { + it('updates the request straight away', function () { expect(controller.request.update).toHaveBeenCalled(); }); - - it('tells the backend to not recalculate balance change', function () { - expect(controller.request.change_balance).toBeUndefined(); - }); - - it('reverts original request times', function () { - expect(moment(controller.request.from_date).format('HH:mm')).toEqual( - moment(requestOriginalDates.from).format('HH:mm')); - expect(moment(controller.request.to_date).format('HH:mm')).toEqual( - moment(requestOriginalDates.to).format('HH:mm')); - }); }); }); - describe('in case leave request is TOIL', function () { + describe('when the popup is closed', function () { beforeEach(function () { - controller.request.request_type = 'toil'; - controller.balance.change.amount--; - - controller.submit(); - spyOn(dialog, 'open'); - $rootScope.$apply(); - }); - - it('ignores balance changes and does not open confirmation dialog', function () { - expect(dialog.open).not.toHaveBeenCalled(); + controller.closeAlert(); }); - it('updates the request straight away', function () { - expect(controller.request.update).toHaveBeenCalled(); + it('flushes any current errors', function () { + expect(controller.errors).toEqual([]); }); }); }); - - describe('when the popup is closed', function () { - beforeEach(function () { - controller.closeAlert(); - }); - - it('flushes any current errors', function () { - expect(controller.errors).toEqual([]); - }); - }); }); describe('manager raises absence request on behalf of staff', function () { diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-leave.controller.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-leave.controller.spec.js index a768c658240..2f2ee7d706c 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-leave.controller.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-leave.controller.spec.js @@ -20,8 +20,8 @@ define([ 'use strict'; describe('RequestModalDetailsLeaveController', function () { - var $componentController, $provide, $log, $rootScope, controller, leaveRequest, - LeaveRequestInstance, selectedAbsenceType; + var $componentController, $provide, $log, $q, $rootScope, controller, leaveRequest, + LeaveRequest, LeaveRequestInstance, selectedAbsenceType; var date2016 = '01/12/2016'; var date2016InServerFormat = moment(helper.getUTCDate(date2016)).format('YYYY-MM-D'); // Must match the date of `date2016` @@ -42,10 +42,12 @@ define([ }])); beforeEach(inject(function ( - _$componentController_, _$log_, _$rootScope_, _LeaveRequestInstance_) { + _$componentController_, _$log_, _$q_, _$rootScope_, _LeaveRequest_, _LeaveRequestInstance_) { $componentController = _$componentController_; $log = _$log_; + $q = _$q_; $rootScope = _$rootScope_; + LeaveRequest = _LeaveRequest_; LeaveRequestInstance = _LeaveRequestInstance_; spyOn($log, 'debug'); @@ -170,6 +172,21 @@ define([ expect(controller.canCalculateChange()).toBe(true); }); }); + + describe('when the unit changes to hours because the absence type changed', function () { + beforeEach(function () { + controller.absenceTypes[1].calculation_unit_name = 'hours'; + controller.request.type_id = controller.absenceTypes[1].id; + + spyOn(controller.request, 'getWorkDayForDate'); + $rootScope.$broadcast('LeaveRequestPopup::absenceTypeChanged'); + $rootScope.$digest(); + }); + + it('does not yet fetch work pattern details for "from" date', function () { + expect(controller.request.getWorkDayForDate).not.toHaveBeenCalled(); + }); + }); }); describe('when unit is in hours', function () { @@ -242,6 +259,118 @@ define([ }); }); + describe('initDayTypesExtended()', function () { + var fromDate, toDate, dayTypeNames; + + beforeEach(function () { + fromDate = moment('2018-01-01').toDate(); + toDate = moment('2018-01-10').toDate(); + }); + + describe('basic tests', function () { + beforeEach(function () { + initDayTypesWithSelectedDateAs('working_day'); + }); + + it('initializes the day types for both date types (from/to)', function () { + expect(controller.loading['fromDayTypes']).toBe(false); + expect(controller.loading['toDayTypes']).toBe(false); + }); + + it('checks for public holiday requests only for the currently selected contact', function () { + var args = LeaveRequest.all.calls.mostRecent().args[0]; + + expect(args.contact_id).toBe(controller.request.contact_id); + }); + }); + + describe('when one of the currently selected dates is a standard working day', function () { + beforeEach(function () { + dayTypeNames = initDayTypesWithSelectedDateAs('working_day'); + }); + + it('sets "all_day", "half_day_am", and "half_day_pm" as the available day types', function () { + expect(dayTypeNames).toEqual(['all_day', 'half_day_am', 'half_day_pm']); + }); + }); + + describe('when there is a "public holiday" leave request for one of the currently selected date', function () { + beforeEach(function () { + dayTypeNames = initDayTypesWithSelectedDateAs('public_holiday'); + }); + + it('sets "public_holiday" as the only available day type', function () { + expect(dayTypeNames).toEqual(['public_holiday']); + }); + }); + + describe('when one of the currently selected date is a non working day', function () { + beforeEach(function () { + dayTypeNames = initDayTypesWithSelectedDateAs('non_working_day'); + }); + + it('sets "non_working_day" as the only available day type', function () { + expect(dayTypeNames).toEqual(['non_working_day']); + }); + }); + + describe('when one of the currently selected date is a weekend', function () { + beforeEach(function () { + dayTypeNames = initDayTypesWithSelectedDateAs('weekend'); + }); + + it('sets "weekend" as the only available day type', function () { + expect(dayTypeNames).toEqual(['weekend']); + }); + }); + + /** + * Initializes the day types list while pretending that the currently selected + * date (for the purpose of the test it doesn't matter if it's the "from" or "to" date) + * is of the given type (working, non working, etc). It then return the list + * of day types for the "from" date + * + * @param {String} type + * @return {Array} + */ + function initDayTypesWithSelectedDateAs (type) { + compileComponent({ + request: LeaveRequestInstance.init({ + contact_id: CRM.vars.leaveAndAbsences.contactId.toString() + }) + }); + + controller.uiOptions.fromDate = fromDate; + controller.uiOptions.toDate = toDate; + + controller.loading['fromDayTypes'] = true; + controller.loading['toDayTypes'] = true; + + mockDateType(type); + + controller.initDayTypesExtended(); + $rootScope.$digest(); + + return controller.requestFromDayTypes.map(function (dayType) { + return dayType.name; + }); + } + + /** + * Mocks the responses of the services that are used to check the type of + * a date, so that they match the given type + * + * @param {String} type + */ + function mockDateType (type) { + spyOn(controller.calendar, 'isNonWorkingDay').and.returnValue($q.resolve(type === 'non_working_day')); + spyOn(controller.calendar, 'isWeekend').and.returnValue($q.resolve(type === 'weekend')); + spyOn(LeaveRequest, 'all').and.returnValue($q.resolve({ + list: type === 'public_holiday' ? [jasmine.any(Object)] : [] + })); + } + }); + describe('can submit', function () { describe('when the leave request has all the details parameters defined', function () { beforeEach(function () { @@ -284,6 +413,32 @@ define([ }); }); + describe('when a leave request is edited', function () { + describe('when the leave request is in hours', function () { + beforeEach(function () { + var absenceType = _.assign(_.cloneDeep(absenceTypeData.all().values[0]), { + calculation_unit_name: 'hours' + }); + + var leaveRequest = LeaveRequestInstance.init({ + from_date: date2016InServerFormat, + to_date: date2016InServerFormat, + type_id: absenceType.id + }); + + compileComponent({ + mode: 'edit', + request: leaveRequest, + absenceTypes: [absenceType] + }); + }); + + it('finishes loading "from" time and shows the selector to UI', function () { + expect(controller.uiOptions.times['from'].loading).toBe(false); + }); + }); + }); + /** * Compiles and initializes the component's controller. It returns the * parameters used to initialize the controller plus default parameter diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-sickness.controller.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-sickness.controller.spec.js index 7be8861140c..1f9371268d2 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-sickness.controller.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-sickness.controller.spec.js @@ -11,8 +11,9 @@ define([ 'leave-absences/mocks/helpers/helper', 'leave-absences/mocks/helpers/request-modal-helper', 'leave-absences/mocks/apis/option-group-api-mock', - 'leave-absences/manager-leave/app' -], function (angular, _, moment, absencePeriodData, absenceTypeData, leaveRequestData, optionGroupMock, helper, requestModalHelper) { + 'leave-absences/manager-leave/app', + 'leave-absences/shared/modules/shared-settings' +], function (angular, _, moment, absencePeriodData, absenceTypeData, leaveRequestData, optionGroupMock, helper, requestModalHelper, crmAngService) { 'use strict'; describe('RequestModalDetailsSicknessController', function () { @@ -40,10 +41,11 @@ define([ }])); beforeEach(inject(function ( - _$componentController_, _$log_, _$rootScope_, _SicknessRequestInstance_) { + _$componentController_, _$log_, _$rootScope_, _crmAngService_, _SicknessRequestInstance_) { $componentController = _$componentController_; $log = _$log_; $rootScope = _$rootScope_; + crmAngService = _crmAngService_; SicknessRequestInstance = _SicknessRequestInstance_; spyOn($log, 'debug'); @@ -110,6 +112,36 @@ define([ }); }); + describe('when users click on the sick reason wrench icon', function () { + var onPopupFormSuccess; + var url; + var sicknessReasons; + + beforeEach(function () { + url = '/civicrm/admin/options/hrleaveandabsences_sickness_reason?reset=1'; + sicknessReasons = optionGroupMock.getCollection('hrleaveandabsences_sickness_reason'); + + spyOn(crmAngService, 'loadForm').and.callFake(function () { + return { + on: function (event, callback) { + if (event === 'crmUnload') { + onPopupFormSuccess = callback; + } + } + }; + }); + controller.openSicknessReasonOptionsEditor(); + }); + + it('calls the crmAngService with the requested url', function () { + expect(crmAngService.loadForm).toHaveBeenCalledWith(url); + }); + + it('loads the sickness reasons', function () { + expect(controller.sicknessReasons).toEqual(_.indexBy(sicknessReasons, 'name')); + }); + }); + describe('open sickness request in edit mode', function () { var sicknessRequest; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-toil.controller.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-toil.controller.spec.js index 08c24b4c0e0..85b5be7bdb3 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-toil.controller.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/controllers/sub-controllers/request-modal-details-toil.controller.spec.js @@ -11,22 +11,26 @@ define([ 'leave-absences/mocks/helpers/helper', 'leave-absences/mocks/helpers/request-modal-helper', 'common/mocks/services/hr-settings-mock', + 'common/services/crm-ang.service', 'leave-absences/mocks/apis/absence-type-api-mock', 'leave-absences/mocks/apis/leave-request-api-mock', 'leave-absences/mocks/apis/option-group-api-mock', 'leave-absences/mocks/apis/public-holiday-api-mock', 'leave-absences/mocks/apis/work-pattern-api-mock', 'leave-absences/manager-leave/app' -], function (angular, _, moment, absencePeriodData, absenceTypeData, leaveRequestData, optionGroupMock, helper, requestModalHelper) { +], function (angular, _, moment, absencePeriodData, absenceTypeData, leaveRequestData, + optionGroupMock, helper, requestModalHelper) { 'use strict'; describe('RequestModalDetailsToilController', function () { - var $componentController, $provide, $q, $log, $rootScope, controller, leaveRequest, - AbsenceType, AbsenceTypeAPI, LeaveRequestInstance, TOILRequestInstance; + var $componentController, $provide, $q, $log, $rootScope, crmAngService, controller, + AbsenceType, AbsenceTypeAPI, leaveRequest, LeaveRequestInstance, + OptionGroup, TOILRequestInstance; var date2016 = '01/12/2016'; var date2016To = '02/12/2016'; // Must be greater than `date2016` var date2017 = '01/02/2017'; + var date2017Server = '2017-01-02'; beforeEach(module('common.mocks', 'leave-absences.templates', 'leave-absences.mocks', 'manager-leave', function (_$provide_) { $provide = _$provide_; @@ -46,20 +50,23 @@ define([ beforeEach(inject(function ( _$componentController_, _$q_, _$log_, _$rootScope_, _AbsenceType_, _AbsenceTypeAPI_, - _LeaveRequestInstance_, _TOILRequestInstance_) { + _crmAngService_, _LeaveRequestInstance_, _OptionGroup_, _TOILRequestInstance_) { $componentController = _$componentController_; $log = _$log_; $q = _$q_; $rootScope = _$rootScope_; AbsenceType = _AbsenceType_; + crmAngService = _crmAngService_; AbsenceTypeAPI = _AbsenceTypeAPI_; LeaveRequestInstance = _LeaveRequestInstance_; + OptionGroup = _OptionGroup_; TOILRequestInstance = _TOILRequestInstance_; spyOn($log, 'debug'); spyOn(AbsenceTypeAPI, 'calculateToilExpiryDate').and.callThrough(); spyOn(AbsenceType, 'canExpire').and.callThrough(); spyOn(AbsenceType, 'calculateToilExpiryDate').and.callThrough(); + spyOn(OptionGroup, 'valuesOf').and.callThrough(); })); describe('on initialize', function () { @@ -85,14 +92,42 @@ define([ expect(controller.isLeaveType('toil')).toBeTruthy(); }); - it('loads toil amounts', function () { + it('loads TOIL accrual options', function () { expect(Object.keys(controller.toilAmounts).length).toBeGreaterThan(0); }); + it('retreives cached TOIL accrual options', function () { + var retreiveCachedTOILOptions = OptionGroup.valuesOf.calls.mostRecent().args[1]; + + expect(retreiveCachedTOILOptions).not.toBe(false); + }); + it('defaults to a multiple day selection', function () { expect(controller.uiOptions.multipleDays).toBe(true); }); + it('sets times bounaries to 00:00 - 23:45', function () { + expect(controller.uiOptions.times.from.min).toBe('00:00'); + expect(controller.uiOptions.times.from.max).toBe('23:45'); + }); + + describe('after TOIL accrual options are loaded', function () { + var toilAmounts, toilAmountsSortedByWeight; + + beforeEach(function () { + toilAmountsSortedByWeight = _.pluck(controller.toilAmounts, function (amount) { + return +amount.weight; + }).sort(); + toilAmounts = _.pluck(controller.toilAmounts, function (amount) { + return +amount.weight; + }); + }); + + it('sorts TOIL accrual options by weight', function () { + expect(toilAmounts).toEqual(toilAmountsSortedByWeight); + }); + }); + describe('when multiple/single days mode changes', function () { describe('when the balance can but fails to be calculated', function () { beforeEach(function () { @@ -129,18 +164,142 @@ define([ }); }); + describe('when both to and from dates and times are set', function () { + beforeEach(function () { + requestModalHelper.setTestDates(controller, '03/18/2018', '03/20/2018'); + requestModalHelper.setTestTimes(controller, '11:30', '16:15'); + }); + + it('sets the maximum duration and accrual values as a difference between to and from date/times in hours', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe(12.5 + 24 + 16.25); + }); + + it('defaults the duration to its maximum', function () { + expect(controller.uiOptions.toil_duration_in_hours).toBe(controller.uiOptions.max_toil_duration_and_accrual); + }); + + it('converts duration into minutes and sets to request', function () { + expect(controller.request.toil_duration).toBe(controller.uiOptions.toil_duration_in_hours * 60); + }); + + describe('when "to" date selected that is greater than "from" date', function () { + beforeEach(function () { + requestModalHelper.setTestDates(controller, '03/22/2018'); + $rootScope.$digest(); + }); + + it('resets "to" time', function () { + expect(controller.uiOptions.times.to.time).toBe(''); + }); + }); + + describe('when single day mode selected', function () { + beforeEach(function () { + controller.uiOptions.multipleDays = false; + + controller.daysSelectionModeChangeHandler(); + $rootScope.$digest(); + }); + + it('resets "to" time', function () { + expect(controller.uiOptions.times.to.time).toBe(''); + }); + + it('resets maximum duration and accrual value', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe(null); + }); + }); + + describe('when from time is greater than to time and then single day mode selected', function () { + beforeEach(function () { + requestModalHelper.setTestTimes(controller, '19:30', '16:15'); + + controller.uiOptions.multipleDays = false; + + controller.daysSelectionModeChangeHandler(); + $rootScope.$digest(); + }); + + it('flushes maximum duration and accrual value', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe(null); + }); + + it('flushes accrual value', function () { + expect(controller.uiOptions.toil_duration_in_hours).toBe(null); + expect(controller.request.toil_duration).toBe(null); + }); + }); + + describe('when the unit changes to "hours" because the absence type changed', function () { + var expectedTOILDurationAndAccrual; + + beforeEach(function () { + changeSelectedAbsenceTypeUnit('hours'); + + expectedTOILDurationAndAccrual = + moment.duration(moment(controller.request.to_date) + .diff(controller.request.from_date)).asHours(); + }); + + it('recalculates TOIL duration', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe( + expectedTOILDurationAndAccrual); + }); + + it('recalculates TOIL accrual value', function () { + expect(controller.request.toil_to_accrue).toBe( + expectedTOILDurationAndAccrual); + }); + }); + + describe('when the request is in hours', function () { + beforeEach(function () { + changeSelectedAbsenceTypeUnit('hours'); + }); + + describe('when duration value has been customised', function () { + beforeEach(function () { + controller.uiOptions.toil_duration_in_hours = 10; + + $rootScope.$digest(); + }); + + it('sets the accrual value to the current value of duration', function () { + expect(controller.request.toil_to_accrue).toBe(controller.uiOptions.toil_duration_in_hours); + }); + }); + + describe('when the unit changes to "days" because the absence type changed', function () { + var expectedTOILDurationAndAccrual; + + beforeEach(function () { + changeSelectedAbsenceTypeUnit('days'); + + expectedTOILDurationAndAccrual = + moment.duration(moment(controller.request.to_date) + .diff(controller.request.from_date)).asHours(); + }); + + it('recalculates TOIL duration', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe( + expectedTOILDurationAndAccrual); + }); + + it('flushes TOIL accrual value', function () { + expect(controller.request.toil_to_accrue).toBe(null); + }); + }); + }); + }); + describe('create', function () { describe('with selected duration and dates', function () { describe('when multiple days request', function () { beforeEach(function () { - var toilAccrue = optionGroupMock.specificObject('hrleaveandabsences_toil_amounts', 'name', 'quarter_day'); - requestModalHelper.setTestDates(controller, date2016, date2016To); - controller.request.toilDurationHours = 1; - controller.request.updateDuration(); - controller.request.toil_to_accrue = toilAccrue.value; + requestModalHelper.setTestTimes(controller, '08:00', '10:00'); - $rootScope.$apply(); + $rootScope.$digest(); }); it('sets expiry date', function () { @@ -149,19 +308,7 @@ define([ it('calls calculateToilExpiryDate on AbsenceType', function () { expect(AbsenceTypeAPI.calculateToilExpiryDate.calls.mostRecent().args[0]).toEqual(controller.request.type_id); - expect(AbsenceTypeAPI.calculateToilExpiryDate.calls.mostRecent().args[1]).toEqual(controller.request.to_date); - }); - - describe('when user changes number of days selected', function () { - beforeEach(function () { - controller.daysSelectionModeChangeHandler(); - }); - - it('does not reset toil attributes', function () { - expect(controller.request.toilDurationHours).not.toEqual('0'); - expect(controller.request.toilDurationMinutes).toEqual('0'); - expect(controller.request.toil_to_accrue).not.toEqual(''); - }); + expect(AbsenceTypeAPI.calculateToilExpiryDate.calls.mostRecent().args[1]).toEqual(moment(controller.request.to_date).format('YYYY-MM-DD')); }); }); @@ -169,10 +316,11 @@ define([ beforeEach(function () { controller.uiOptions.multipleDays = false; requestModalHelper.setTestDates(controller, date2016); + requestModalHelper.setTestTimes(controller, '08:00', '10:00'); }); it('calls calculateToilExpiryDate on AbsenceType', function () { - expect(AbsenceTypeAPI.calculateToilExpiryDate.calls.mostRecent().args[1]).toEqual(controller.request.from_date); + expect(AbsenceTypeAPI.calculateToilExpiryDate.calls.mostRecent().args[1]).toEqual(moment(controller.request.from_date).format('YYYY-MM-DD')); }); }); }); @@ -184,6 +332,9 @@ define([ beforeEach(function () { toilRequest = TOILRequestInstance.init(leaveRequestData.findBy('request_type', 'toil')); toilRequest.contact_id = CRM.vars.leaveAndAbsences.contactId.toString(); + toilRequest.from_date = '2018-03-04 12:00'; + toilRequest.to_date = '2018-03-06 10:00'; + toilRequest.toil_duration = 120; compileComponent({ leaveType: 'toil', @@ -215,6 +366,91 @@ define([ it('shows balance', function () { expect(controller.uiOptions.showBalance).toBeTruthy(); }); + + it('sets times', function () { + expect(controller.uiOptions.times.from.time).toBe('12:00'); + expect(controller.uiOptions.times.to.time).toBe('10:00'); + }); + + it('sets maximum duration', function () { + expect(controller.uiOptions.max_toil_duration_and_accrual).toBe(12 + 24 + 10); + }); + + it('sets custom duration', function () { + expect(controller.uiOptions.toil_duration_in_hours).toBe(2); + }); + }); + + describe('when user opens TOIL accrual options group editor', function () { + var onPopupFormSuccess; + + beforeEach(function () { + // flushing TOIL accrual options + controller.toilAmounts = null; + // saving the callback on the popup close to imitate its call later + spyOn(crmAngService, 'loadForm').and.callFake(function () { + return { + on: function (event, callback) { + if (event === 'crmUnload') { + onPopupFormSuccess = callback; + } + } + }; + }); + + controller.openToilInDaysAccrualOptionsEditor(); + }); + + it('calls the CRM.loadForm with according URL', function () { + expect(crmAngService.loadForm).toHaveBeenCalledWith('/civicrm/admin/options/hrleaveandabsences_toil_amounts?reset=1'); + }); + + describe('when TOIL accruals editor is closed', function () { + beforeEach(function () { + onPopupFormSuccess(); + $rootScope.$digest(); + }); + + it('reloads TOIL accrual options', function () { + expect(Object.keys(controller.toilAmounts).length).toBeGreaterThan(0); + }); + + it('fetches updated TOIL accrual options from the backend', function () { + var retreiveCachedTOILOptions = OptionGroup.valuesOf.calls.mostRecent().args[1]; + + expect(retreiveCachedTOILOptions).toBe(false); + }); + }); + }); + }); + + describe('TOIL accrual options group editor icon', function () { + ['admin-dashboard', 'absence-tab'].forEach(function (siteSection) { + describe('when the leave request modal is opened in ' + siteSection + ' section', function () { + beforeEach(function () { + $rootScope.section = siteSection; + + compileComponent({ request: TOILRequestInstance.init() }); + }); + + it('shows the editor icon', function () { + expect(controller.showTOILAccrualsOptionEditorIcon).toBe(true); + }); + }); + }); + + ['manager-leave', 'my-leave'].forEach(function (siteSection) { + describe('when the leave request modal is opened in ' + siteSection + ' section', function () { + beforeEach(function () { + $rootScope.section = siteSection; + + compileComponent({ request: TOILRequestInstance.init() }); + }); + + it('does not show the editor icon', function () { + expect(controller.showTOILAccrualsOptionEditorIcon).toBe(false); + }); + }); }); }); @@ -287,7 +523,7 @@ define([ expect(controller.request.toil_expiry_date).toEqual(oldExpiryDate); }); - it('has toil amount set by manager', function () { + it('has TOIL amount set by manager', function () { expect(controller.request.toil_to_accrue).toEqual(originalToilToAccrue.value); }); }); @@ -376,7 +612,7 @@ define([ role: 'manager', request: toilRequest }); - controller.request.to_date = date2017; + controller.request.to_date = date2017Server; controller.onDateChangeExtended(); $rootScope.$digest(); }); @@ -394,7 +630,7 @@ define([ role: 'staff', request: toilRequest }); - controller.request.to_date = date2017; + controller.request.to_date = date2017Server; controller.onDateChangeExtended(); $rootScope.$digest(); }); @@ -581,6 +817,18 @@ define([ }); }); + /** + * Changes selected absence type unit + * + * @param {String} unit days|hours + */ + function changeSelectedAbsenceTypeUnit (unit) { + controller.selectedAbsenceType.calculation_unit_name = unit; + + controller.onAbsenceTypeUpdateExtended(); + $rootScope.$digest(); + } + /** * Compiles and initializes the component's controller. It returns the * parameters used to initialize the controller plus default parameter diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/instances/toil-request.instance.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/instances/toil-request.instance.spec.js index e2e247faa64..dd52a3e6240 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/instances/toil-request.instance.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/instances/toil-request.instance.spec.js @@ -48,9 +48,9 @@ define([ expect(instance).toBeDefined(); }); - it('default toil Duration value is set', function () { - expect(instance.toilDurationHours).toBe('0'); - expect(instance.toilDurationMinutes).toBe('0'); + it('default fields for backend are set', function () { + expect(instance.from_date_amount).toBe(0); + expect(instance.to_date_amount).toBe(0); }); it('initializes request type', function () { @@ -58,32 +58,11 @@ define([ }); }); - describe('updateDuration()', function () { - beforeEach(function () { - instance = TOILRequestInstance.init({}, false); - instance.toilDurationHours = 1; - instance.toilDurationMinutes = 1; - instance.updateDuration(); - }); - - it('updates durations in minutes', function () { - expect(instance.toil_duration).toEqual(61); - }); - }); - describe('edit toil', function () { beforeEach(function () { var toilRequest = requestMockData.findBy('request_type', 'toil'); instance = TOILRequestInstance.init(toilRequest); }); - - it('sets duration hours', function () { - expect(instance.toilDurationHours).toEqual('3'); - }); - - it('sets duration minutes', function () { - expect(instance.toilDurationMinutes).toEqual('1'); - }); }); }); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/models/absence-type.model.spec.js b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/models/absence-type.model.spec.js index 948f9a276f9..e24bc5f7ce2 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/models/absence-type.model.spec.js +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/js/angular/test/shared/models/absence-type.model.spec.js @@ -10,7 +10,7 @@ define([ 'use strict'; describe('AbsenceType', function () { - var $provide, AbsenceType, AbsenceTypeAPI, OptionGroupAPI, $rootScope, $q; + var $provide, $q, $rootScope, AbsenceType, AbsenceTypeAPI, OptionGroup; beforeEach(module('leave-absences.models', 'leave-absences.mocks', function (_$provide_) { $provide = _$provide_; @@ -20,21 +20,20 @@ define([ $provide.value('AbsenceTypeAPI', _AbsenceTypeAPIMock_); })); - beforeEach(inject(['api.optionGroup.mock', 'api.optionGroup.mock', function (_OptionGroupAPI_, _OptionGroupAPIMock_) { - OptionGroupAPI = _OptionGroupAPI_; - + beforeEach(inject(['api.optionGroup.mock', function (_OptionGroupAPIMock_) { $provide.value('api.optionGroup', _OptionGroupAPIMock_); }])); - beforeEach(inject(function (_AbsenceType_, _AbsenceTypeAPI_, _$rootScope_, _$q_) { - AbsenceType = _AbsenceType_; - AbsenceTypeAPI = _AbsenceTypeAPI_; + beforeEach(inject(function (_$q_, _$rootScope_, _AbsenceType_, _AbsenceTypeAPI_, _OptionGroup_) { $q = _$q_; $rootScope = _$rootScope_; + AbsenceType = _AbsenceType_; + AbsenceTypeAPI = _AbsenceTypeAPI_; + OptionGroup = _OptionGroup_; spyOn(AbsenceTypeAPI, 'all').and.callThrough(); spyOn(AbsenceTypeAPI, 'calculateToilExpiryDate').and.callThrough(); - spyOn(OptionGroupAPI, 'valuesOf').and.callThrough(); + spyOn(OptionGroup, 'valuesOf').and.callThrough(); })); it('has expected interface', function () { @@ -156,7 +155,7 @@ define([ }); it('retrieves calculation unit option group', function () { - expect(OptionGroupAPI.valuesOf).toHaveBeenCalledWith( + expect(OptionGroup.valuesOf).toHaveBeenCalledWith( 'hrleaveandabsences_absence_type_calculation_unit'); }); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_absence-work-patterns.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_absence-work-patterns.scss index 962a3cb53b1..b9d628d75ce 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_absence-work-patterns.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_absence-work-patterns.scss @@ -1,3 +1,7 @@ +.chr_absence-work-pattern__add-custom { + margin-bottom: 20px; +} + .chr_absence-work-pattern__custom-work-pattern { td:nth-child(1) { width: 40%; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/annual-entitlement-change-log.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_annual-entitlement-change-log.scss similarity index 52% rename from uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/annual-entitlement-change-log.scss rename to uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_annual-entitlement-change-log.scss index 45ba34906cc..988e40700a8 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/annual-entitlement-change-log.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_annual-entitlement-change-log.scss @@ -1,9 +1,9 @@ .annual-entitlement-change-log-component { - table thead td { + thead td { min-width: 100px; } - table thead td.annual-entitlement-change-log-component__comments { + thead .annual-entitlement-change-log-component__comments { min-width: 300px; } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-calendar.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-calendar.scss index 5374c93d5f1..e4766859fd4 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-calendar.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-calendar.scss @@ -6,6 +6,8 @@ $chr-leave-calendar-legend-size: 20px; .chr_leave-calendar__dates-container { + overflow-x: auto; + .chr_leave-calendar { @media (min-width: $screen-lg-min) { table-layout: fixed; @@ -40,7 +42,7 @@ $chr-leave-calendar-legend-size: 20px; .chr_leave-calendar__item { - color: #FFF; + color: #fff; display: block; font-size: $chr-leave-calendar-cell-font-size; height: 100%; @@ -61,8 +63,25 @@ $chr-leave-calendar-legend-size: 20px; } > a { - cursor: pointer; @include absolute-centered(); + cursor: pointer; + } +} + +.chr_leave-calendar__item--half { + height: 50%; + + &:not(:first-child) { + height: calc(50% - 1px); + margin-top: 1px; + } +} + +.chr_leave-calendar__item--more { + border: 2px solid #d3dee2; + + .chr_leave-calendar__item__label { + color: #4d4d69; } } @@ -78,59 +97,39 @@ $chr-leave-calendar-legend-size: 20px; border-color: #eca67e; } -.chr_leave-calendar__item--type--non-working { - background-color: #41afcb !important; - border-color: #41afcb; +.chr_leave-calendar__day-container--type--non-working { + background-color: #41afcb; } -.chr_leave-calendar__item--type--public-holiday { - background-color: #8ec68a !important; - border-color: #8ec68a; +.chr_leave-calendar__day-container--type--public-holiday { + background-color: #8ec68a; } -.chr_leave-calendar__item--type--weekend { - background-color: #c7cbd0 !important; - border-color: #c7cbd0; +.chr_leave-calendar__day-container--type--weekend { + background-color: #c7cbd0; } .chr_leave-calendar__item--alt { - background: #FFF !important; + background-color: #fff !important; border: 1px solid transparent; color: $gray-darker; } .chr_leave-calendar__item--requested { + @include striped-background(rgba(255, 255, 255, 0.3)); - &:before { - background: $chr-leave-calendar-item-requested-border-color; - content: ''; - display: block; - height: $chr-leave-calendar-item-requested-border-height; - position: absolute; - width: 100%; - top: 0; - } -} - -.chr_leave-calendar__item--toil-requested { - - &:before { - background: red; - content: ''; - display: block; - height: $chr-leave-calendar-item-requested-border-height; - left: -1px; - position: absolute; - width: calc(100% + 2px); - top: -1px; + &.chr_leave-calendar__item--alt { + @include striped-background(rgba(0, 0, 0, 0.1)); } } .chr_leave-calendar__items { - > td { - overflow: hidden; height: $chr-leave-calendar-cell-height; + overflow: hidden; + } + + .chr_leave-calendar__items_day-cell { padding: 0 !important; } @@ -140,12 +139,15 @@ $chr-leave-calendar-legend-size: 20px; } } +.chr_leave-calendar__day-container { + height: 100%; +} + .chr_leave-calendar__legend__title { font-size: $font-size-small; } .chr_leave-calendar__legend { - > .row:not(:first-child) { margin-top: 20px; } @@ -190,8 +192,7 @@ $chr-leave-calendar-legend-size: 20px; } } -td.chr_leave-calendar__name, -th.chr_leave-calendar__name { +.chr_leave-calendar__name { font-size: $font-size-small !important; line-height: 100%; padding: 0 20px !important; @@ -200,15 +201,16 @@ th.chr_leave-calendar__name { width: 100%; } -th.chr_leave-calendar__name, th.chr_leave-calendar__day { +.chr_leave-calendar__name_header, +.chr_leave-calendar__day { height: 49px; } -th.chr_leave-calendar__name { +.chr_leave-calendar__name_header { padding-bottom: 10px !important; } -td.chr_leave-calendar__name { +.chr_leave-calendar__name_cell { vertical-align: middle !important; } @@ -216,24 +218,22 @@ td.chr_leave-calendar__name { font-size: $chr-leave-calendar-cell-font-size; text-align: center; - [class*="btn"] { + [class*='btn'] { + line-height: 1em; outline: none; padding: 0; - line-height: 1em; .fa { color: $gray; } &[disabled] { - .fa { opacity: 0.5; } } &:hover:not([disabled]) { - .fa { color: $gray-darker; } @@ -242,7 +242,7 @@ td.chr_leave-calendar__name { } .chr_leave-calendar__pagination-next { - border-top: none; + border-top: 0; th { height: 24px; @@ -262,10 +262,6 @@ td.chr_leave-calendar__name { } } -.chr_leave-calendar__dates-container { - overflow-x: auto; -} - .chr_leave-calendar__admin-filters-hint { display: inline-block; font-size: 20px; @@ -273,7 +269,7 @@ td.chr_leave-calendar__name { } .chr_leave-calendar__admin-filters-select { - width: calc(100% - 50px); display: inline-block; margin-right: 20px; + width: calc(100% - 50px); } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-request-record-actions.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-request-record-actions.scss new file mode 100644 index 00000000000..73811ddf599 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave-request-record-actions.scss @@ -0,0 +1,35 @@ +leave-request-record-actions { + display: block; + + .btn-group { + float: left; + } + + .btn-group:first-child { + margin-right: $crm-gap-medium; + + .dropdown-menu { + left: auto; + right: 0; + } + } +} + +@media screen and (max-width: $screen-xs-max) { + leave-request-record-actions { + .btn-group { + width: calc((100% - #{$crm-gap-medium}) / 2); + } + + .btn { + padding-left: 0; + padding-right: 0; + width: 100%; + } + + .btn-group:first-child .dropdown-menu { + left: 0; + right: auto; + } + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave.scss index 2788714152a..6f4c41aa631 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/_leave.scss @@ -4,7 +4,7 @@ $leave-taller-input-height: 40px; margin-right: 5px; position: relative; top: 1px; - width: calc(100% - 80px); + width: 100%; select { height: $leave-taller-input-height; @@ -15,18 +15,3 @@ $leave-taller-input-height: 40px; width: $leave-taller-input-height; } } - -leave-request-record-actions { - .dropdown-menu { - left: auto; - right: 0; - } - - .dropdown-toggle { - height: $leave-taller-input-height; - } - - i.fa { - margin-right: 8px; - } -} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/outside-namespace/_leave-calendar.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/outside-namespace/_leave-calendar.scss new file mode 100644 index 00000000000..01dcf9d5315 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/components/outside-namespace/_leave-calendar.scss @@ -0,0 +1,31 @@ +$chr-leave-calendar-tooltip-shadow: 0 3px 8px 0 rgba(49, 40, 40, 0.25); +$chr-leave-calendar-tooltip-item-min-width: 154px; + +// @TODO the tooltip style should be moved to the global styling +.chr_leave-calendar__day-tooltip { + &.tooltip.in { + opacity: 1; + } + + .tooltip-arrow { + border-top-color: $crm-white !important; + } + + .tooltip-inner { + background-color: $crm-white; + border-radius: 0; + box-shadow: $chr-leave-calendar-tooltip-shadow; + color: $gray-darker; + padding: 0; + } +} + +.chr_leave-calendar__day-tooltip_item { + cursor: pointer; + min-width: $chr-leave-calendar-tooltip-item-min-width; + padding: $crm-gap-medium; + + &:hover { + background-color: $gray-light; + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/leaveandabsence.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/leaveandabsence.scss index 1c4a2baa688..06c12399691 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/leaveandabsence.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/leaveandabsence.scss @@ -1,18 +1,20 @@ -@import "SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/mixins/ALL"; -@import "overrides/variables"; -@import "mixins/*"; +@import 'SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/mixins/ALL'; +@import 'overrides/variables'; +@import 'mixins/*'; #bootstrap-theme { - @import "base/helpers/*"; - @import "overrides/style/*"; - @import "components/*"; - @import "directives/*"; - @import "pages/*"; + @import 'base/helpers/*'; + @import 'overrides/style/*'; + @import 'components/*'; + @import 'directives/*'; + @import 'pages/*'; } +@import 'components/outside-namespace/*'; + // The bootstrap dropdown is attached to the outside of the #bootstrap-theme // namespace. Hence unfortunately the styles for the dropdowns need // to be available out of the namespace as well -@import "SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/mixins/ALL"; -@import "SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/_dropdowns.scss"; -@import "SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/overrides/style/_dropdowns.scss"; +@import 'SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/mixins/ALL'; +@import 'SCSSROOT/org.civicrm.shoreditch/base/scss/vendor/bootstrap/dropdowns'; +@import 'SCSSROOT/org.civicrm.shoreditch/scss/bootstrap/overrides/style/dropdowns'; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/mixins/_gradients.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/mixins/_gradients.scss new file mode 100644 index 00000000000..23e156f3f70 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/mixins/_gradients.scss @@ -0,0 +1,3 @@ +@mixin striped-background($stripe-color) { + background: repeating-linear-gradient(45deg, $stripe-color, $stripe-color 5px, transparent 5px, transparent 8px); +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_absence-tab-page.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_absence-tab-page.scss index 6787c3be2d1..656300104a6 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_absence-tab-page.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_absence-tab-page.scss @@ -1,12 +1,4 @@ .absence-tab-page { - .btn-group { - margin-bottom: 20px; - - > .btn { - border-color: transparent !important; - } - } - .tab-pane { padding: 0 !important; } @@ -14,4 +6,8 @@ .tab-content { background-color: transparent !important; } + + leave-request-record-actions { + margin-bottom: 20px; + } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_admin-dashboard-page.scss b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_admin-dashboard-page.scss index 7486864d8e1..53017223e46 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_admin-dashboard-page.scss +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/scss/pages/_admin-dashboard-page.scss @@ -3,7 +3,9 @@ $content-container-margin: 16px; @at-root { .page-civicrm-leaveandabsences-dashboard { - h1.page-title, + + /* stylelint-disable selector-max-id */ + .page-title, #branding { display: none !important; } @@ -12,6 +14,7 @@ $content-container-margin: 16px; margin: 0; padding: 0; } + /* stylelint-enable */ } .admin-dashboard-page { @@ -19,33 +22,29 @@ $content-container-margin: 16px; .crm_page__topbar { height: 65px; + } - .dropdown-toggle { - margin: 15px 30px 0 0 !important; - - +ul { - margin-right: 30px !important; - } - } + leave-request-record-actions { + margin: 12px #{$content-container-margin} 0 0; } .chr_admin-dashboard_side-nav { + background-color: $crm-white; + height: calc(100% - 12px); overflow: hidden; - width: $navigation-column-width; position: absolute; - height: calc(100% - 12px); - background-color: $crm-white; + width: $navigation-column-width; - li.active { + .active { background: $gray-light; } } .chr_admin-dashboard_content { float: right; - width: calc(100% - #{$navigation-column-width} - #{$content-container-margin} * 2); margin: $content-container-margin; margin-bottom: 0; + width: calc(100% - #{$navigation-column-width} - #{$content-container-margin} * 2); } } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/sql/auto_install.sql b/uk.co.compucorp.civicrm.hrleaveandabsences/sql/auto_install.sql index 0f150460bb6..22fc0da4816 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/sql/auto_install.sql +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/sql/auto_install.sql @@ -414,3 +414,26 @@ CREATE TABLE `civicrm_hrleaveandabsences_leave_period_entitlement_log` ( CONSTRAINT FK_civicrm_hrlaa_leave_period_entitlement_log_entitlement_id FOREIGN KEY (`entitlement_id`) REFERENCES `civicrm_hrleaveandabsences_leave_period_entitlement`(`id`) ON DELETE CASCADE, CONSTRAINT FK_civicrm_hrlaa_leave_period_entitlement_log_editor_id FOREIGN KEY (`editor_id`) REFERENCES `civicrm_contact`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ; + +-- /******************************************************* +-- * +-- * civicrm_hrleaveandabsences_leave_balance_change_expiry_log +-- * +-- * Leave Balance Change Expiry Log +-- * +-- *******************************************************/ +CREATE TABLE `civicrm_hrleaveandabsences_leave_balance_change_expiry_log` ( + + + `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'Unique LeaveBalanceChangeExpiryLog ID', + `balance_change_id` int unsigned NOT NULL COMMENT 'The expired balance change ID', + `amount` decimal(20,2) NOT NULL DEFAULT 0 COMMENT 'The expired balance amount', + `source_id` int unsigned NOT NULL COMMENT 'Expired Balance change source ID', + `source_type` varchar(20) NOT NULL COMMENT 'Expired Balance change source type', + `expiry_date` date NOT NULL COMMENT 'The balance change expiry date', + `balance_type_id` int unsigned NOT NULL COMMENT 'One of the values of the Leave Balance Type option group', + `leave_date` date COMMENT 'The Leave date of the expired balance change (i.e If it is a leave request balance change)', + `leave_request_id` int unsigned COMMENT 'The Leave Request ID linked to the expired balance change (i.e If it is a leave request balance change)', + `created_date` datetime COMMENT 'The date and time this log was created' , + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/ManageEntitlements.tpl b/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/ManageEntitlements.tpl index 928a2b1367c..58875a81b3b 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/ManageEntitlements.tpl +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/ManageEntitlements.tpl @@ -14,19 +14,19 @@ {/foreach}
    -
    -
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/WorkPattern/Calendar.tpl b/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/WorkPattern/Calendar.tpl index d9f262e6ac8..3063dee0c62 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/WorkPattern/Calendar.tpl +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/templates/CRM/HRLeaveAndAbsences/Form/WorkPattern/Calendar.tpl @@ -78,7 +78,16 @@ {$form.weeks[$smarty.section.i.index].days.6.number_of_hours.html} - {ts}Leave days{/ts} {help id="id-leave-days"} + + {ts}Leave days{/ts} {help id="id-leave-days"} +
    + + + {$form.weeks[$smarty.section.i.index].days.0.leave_days.html} {$form.weeks[$smarty.section.i.index].days.1.leave_days.html} {$form.weeks[$smarty.section.i.index].days.2.leave_days.html} @@ -95,6 +104,14 @@ {/literal} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDatesTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDatesTest.php index 7862e5d9280..0baf8065308 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDatesTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/API/Wrapper/LeaveRequestDatesTest.php @@ -99,10 +99,32 @@ public function testTheOutputIsNeverChanged() { $this->assertEquals($result, $wrappedResult); } + public function testDateRangesAreAdjusted() { + $apiRequest = [ + 'entity' => 'LeaveRequest', + 'action' => 'get', + 'params' => [ + 'from_date' => ['BETWEEN' => ['2016-02-01', '2016-03-01']], + 'to_date' => ['NOT IN' => ['2016-04-01', '2016-04-21', '2016-04-30']], + ] + ]; + + $wrappedRequest = $this->wrapper->fromApiInput($apiRequest); + + $fromDate = $wrappedRequest['params']['from_date']; + $expectedFromDate = ['2016-02-01 00:00:00', '2016-03-01 00:00:00']; + $this->assertEquals($expectedFromDate, $fromDate['BETWEEN']); + + $toDate = $wrappedRequest['params']['to_date']; + $expectedToDate = ['2016-04-01 23:59:59', '2016-04-21 23:59:59', '2016-04-30 23:59:59']; + $this->assertEquals($expectedToDate, $toDate['NOT IN']); + } + public function supportedActions() { return [ ['get'], ['getfull'] ]; } + } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLogTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLogTest.php new file mode 100644 index 00000000000..794b87efc88 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeExpiryLogTest.php @@ -0,0 +1,133 @@ + 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'amount' => 3, + ]); + } + + /** + * @expectedException CRM_HRLeaveAndAbsences_Exception_InvalidLeaveBalanceChangeExpiryLogException + * @expectedExceptionMessage The source_id field should not be empty + */ + public function testCreateThrowsExceptionWhenSourceIdIsAbsent() { + LeaveBalanceChangeExpiryLog::create([ + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'amount' => 3, + 'balance_change_id' => 1, + ]); + } + + /** + * @expectedException CRM_HRLeaveAndAbsences_Exception_InvalidLeaveBalanceChangeExpiryLogException + * @expectedExceptionMessage The source_type field should not be empty + */ + public function testCreateThrowsExceptionWhenSourceTypeIsAbsent() { + LeaveBalanceChangeExpiryLog::create([ + 'source_id' => 1, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'amount' => 3, + 'balance_change_id' => 1, + ]); + } + + /** + * @expectedException CRM_HRLeaveAndAbsences_Exception_InvalidLeaveBalanceChangeExpiryLogException + * @expectedExceptionMessage The expiry_date field should not be empty + */ + public function testCreateThrowsExceptionWhenExpiryDateIsAbsent() { + LeaveBalanceChangeExpiryLog::create([ + 'source_id' => 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'balance_type_id' => 1, + 'amount' => 3, + 'balance_change_id' => 1, + ]); + } + + /** + * @expectedException CRM_HRLeaveAndAbsences_Exception_InvalidLeaveBalanceChangeExpiryLogException + * @expectedExceptionMessage The amount field should not be empty + */ + public function testCreateThrowsExceptionWhenAmountIsAbsent() { + LeaveBalanceChangeExpiryLog::create([ + 'source_id' => 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'balance_change_id' => 1, + ]); + } + + public function testCreateDoesNotThrowExceptionWhenAmountIsZero() { + $expiryLog = LeaveBalanceChangeExpiryLog::create([ + 'balance_change_id' => 1, + 'source_id' => 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'amount' => 0, + ]); + + $this->assertNotNull($expiryLog->id); + } + + public function testUpdatesNotAllowedForTheLeaveBalanceChangeExpiryLogEntity() { + $params = [ + 'balance_change_id' => 1, + 'source_id' => 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2017-02-01'), + 'balance_type_id' => 1, + 'amount' => 3, + 'leave_date' => CRM_Utils_Date::processDate('2017-01-01'), + 'leave_request_id' => 1, + ]; + + $expiryLog = LeaveBalanceChangeExpiryLog::create($params); + $this->setExpectedException( + CRM_HRLeaveAndAbsences_Exception_InvalidLeaveBalanceChangeExpiryLogException::class, + 'Updates not allowed for the LeaveBalanceChange Expiry Log entity' + ); + + $params['id'] = $expiryLog->id; + LeaveBalanceChangeExpiryLog::create($params); + } + + public function testTheCreatedDateCanNotBeManipulated() { + $params = [ + 'balance_change_id' => 1, + 'source_id' => 1, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => CRM_Utils_Date::processDate('2016-01-01'), + 'balance_type_id' => 1, + 'amount' => 3, + 'created_date' => CRM_Utils_Date::processDate('2016-01-01') + ]; + + $dateNow = new DateTime(); + $expiryLog = LeaveBalanceChangeExpiryLog::create($params); + $this->assertEquals($dateNow, new DateTime($expiryLog->created_date), 10); + } +} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeTest.php index 3ab41e63fa6..4dffab58a2c 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveBalanceChangeTest.php @@ -12,6 +12,7 @@ use CRM_HRLeaveAndAbsences_Test_Fabricator_LeavePeriodEntitlement as LeavePeriodEntitlementFabricator; use CRM_Hrjobcontract_Test_Fabricator_HRJobContract as HRJobContractFabricator; use CRM_HRLeaveAndAbsences_Factory_LeaveDateAmountDeduction as LeaveDateAmountDeductionFactory; +use CRM_HRLeaveAndAbsences_BAO_LeaveBalanceChangeExpiryLog as LeaveBalanceChangeExpiryLog; /** * Class CRM_HRLeaveAndAbsences_BAO_LeaveBalanceChangeTest @@ -544,7 +545,7 @@ public function testTheEntitlementBreakdownSumsOnlyThePositiveLeaveBroughtForwar // This will deduct 11 days, but the respective balance changes // won't be returned as part of the breakdown $this->createLeaveRequestBalanceChange( - $entitlement->id, + $entitlement->type_id, $leaveRequestStatuses['approved'], date('Y-m-d'), date('Y-m-d', strtotime('+10 days')) @@ -3559,6 +3560,148 @@ public function testCalculateAmountForDateReturnsZeroWhenContactWorkDayIsNull() $this->assertEquals(0, $amount); } + public function testCreateExpiryRecordsLogsExpiredBalanceChanges() { + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2017-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2017-12-31') + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'contact_id' => 1, + 'period_id' => $absencePeriod->id, + 'type_id' => 1, + ]); + + $broughtForwardAmount = 5; + $broughtForwardExpiryDate = new DateTime('2017-04-01'); + $broughtForwardBalance = $this->createBroughtForwardBalanceChange( + $periodEntitlement->id, + $broughtForwardAmount, + $broughtForwardExpiryDate->format('YmdHis') + ); + + $toilLeaveDate = new DateTime('2017-05-17'); + $toilExpiryDate = new DateTime('2017-08-01'); + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'contact_id' => $periodEntitlement->contact_id, + 'type_id' => $periodEntitlement->type_id, + 'from_date' => $toilLeaveDate->format('YmdHis'), + 'to_date' => $toilLeaveDate->format('YmdHis'), + 'toil_expiry_date' => $toilExpiryDate->format('YmdHis'), + 'toil_to_accrue' => 1, + 'toil_duration' => 100, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], true); + + LeaveBalanceChange::createExpiryRecords(); + + $balanceExpiryLogs = $this->getBalanceChangeExpiryLogRecords(); + $this->assertCount(2, $balanceExpiryLogs); + + //Get the expiry balance record for the TOIL balance change + $toilBalanceChange = $this->findToilRequestMainBalanceChange($toilRequest->id); + $toilExpiryRecord = $this->getExpiryRecordForBalanceChange($toilBalanceChange->id); + $toilDate = $toilRequest->getDates()[0]; + + //Get expiry balance record for the brought forward balance change + $broughtForwardExpiryRecord = $this->getExpiryRecordForBalanceChange($broughtForwardBalance->id); + + $expectedToilLog = [ + 'id' => $balanceExpiryLogs[$toilExpiryRecord->id]['id'], + 'balance_change_id' => $toilExpiryRecord->id, + 'amount' => -1 * $toilRequest->toil_to_accrue, + 'source_id' => $toilDate->id, + 'source_type' => LeaveBalanceChange::SOURCE_LEAVE_REQUEST_DAY, + 'expiry_date' => $toilExpiryDate->format('Y-m-d'), + 'balance_type_id' => $toilExpiryRecord->type_id, + 'leave_date' => $toilLeaveDate->format('Y-m-d'), + 'leave_request_id' => $toilRequest->id + ]; + + $expectedBroughtForwardLog = [ + 'id' => $balanceExpiryLogs[$broughtForwardExpiryRecord->id]['id'], + 'balance_change_id' => $broughtForwardExpiryRecord->id, + 'amount' => -1 * $broughtForwardAmount, + 'source_id' => $periodEntitlement->id, + 'source_type' => LeaveBalanceChange::SOURCE_ENTITLEMENT, + 'expiry_date' => $broughtForwardExpiryDate->format('Y-m-d'), + 'balance_type_id' => $broughtForwardExpiryRecord->type_id, + 'leave_date' => NULL, + 'leave_request_id' => NULL + ]; + + $dateNow = new DateTime(); + $this->assertEquals($dateNow, new DateTime($balanceExpiryLogs[$toilExpiryRecord->id]['created_date']), 10); + $this->assertEquals($dateNow, new DateTime($balanceExpiryLogs[$broughtForwardExpiryRecord->id]['created_date']), 10); + + //we need to remove the created dates from the array as its not possible to assert the exact value. + unset($balanceExpiryLogs[$toilExpiryRecord->id]['created_date']); + unset($balanceExpiryLogs[$broughtForwardExpiryRecord->id]['created_date']); + + $this->assertEquals($expectedToilLog, $balanceExpiryLogs[$toilExpiryRecord->id]); + $this->assertEquals($expectedBroughtForwardLog, $balanceExpiryLogs[$broughtForwardExpiryRecord->id]); + } + + public function testCreateExpiryRecordsDoesNotExpireBalanceChangesLinkedToSoftDeletedToilRequest() { + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2017-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2017-12-31') + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'contact_id' => 1, + 'period_id' => $absencePeriod->id, + 'type_id' => 1, + ]); + + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'contact_id' => $periodEntitlement->contact_id, + 'type_id' => $periodEntitlement->type_id, + 'from_date' => CRM_Utils_Date::processDate('2017-05-17'), + 'to_date' => CRM_Utils_Date::processDate('2017-05-17'), + 'toil_expiry_date' => CRM_Utils_Date::processDate('2017-08-01'), + 'toil_to_accrue' => 1, + 'toil_duration' => 100, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], TRUE); + + $toilRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ + 'contact_id' => $periodEntitlement->contact_id, + 'type_id' => $periodEntitlement->type_id, + 'from_date' => CRM_Utils_Date::processDate('2017-08-09'), + 'to_date' => CRM_Utils_Date::processDate('2017-08-09'), + 'toil_expiry_date' => CRM_Utils_Date::processDate('2017-11-01'), + 'toil_to_accrue' => 1, + 'toil_duration' => 100, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], TRUE); + + //Delete the first TOIL request + LeaveRequest::softDelete($toilRequest->id); + + LeaveBalanceChange::createExpiryRecords(); + $toilBalanceChange = $this->findToilRequestMainBalanceChange($toilRequest2->id); + $toilExpiryRecord = $this->getExpiryRecordForBalanceChange($toilBalanceChange->id); + + //only the expiry record second TOIL request will be created since the first is deleted. + $balanceExpiryLogs = $this->getBalanceChangeExpiryLogRecords(); + $this->assertCount(1, $balanceExpiryLogs); + $this->assertNotNull($balanceExpiryLogs[$toilExpiryRecord->id]); + } + + private function getBalanceChangeExpiryLogRecords() { + $leaveExpiryLog = new LeaveBalanceChangeExpiryLog(); + $leaveExpiryLog->find(); + + $records = []; + while($leaveExpiryLog->fetch()) { + $records[$leaveExpiryLog->balance_change_id] = $leaveExpiryLog->toArray() ; + } + + return $records; + } + + private function getBalanceChangesForPeriodEntitlement($leavePeriodEntitlement) { $record = new LeaveBalanceChange(); $record->source_id = $leavePeriodEntitlement->id; diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeavePeriodEntitlementTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeavePeriodEntitlementTest.php index 266252404d7..1cd3d0d9123 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeavePeriodEntitlementTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeavePeriodEntitlementTest.php @@ -305,7 +305,7 @@ public function testGetEntitlementShouldIncludeOnlyPositiveLeaveBroughtForwardAn $this->createPublicHolidayBalanceChange($periodEntitlement->id, 8); $this->createLeaveRequestBalanceChange( - $periodEntitlement->id, + $periodEntitlement->type_id, $this->leaveRequestStatuses['approved'], date('Y-m-d'), date('Y-m-d', strtotime('+2 days')) @@ -1723,13 +1723,14 @@ public function testGetEntitlementsForContactsDoesNotIncludeLeaveRequestBalanceC } public function testGetBalanceShouldNotIncludeBalanceForExcludedLeaveRequests() { + $absenceType = AbsenceTypeFabricator::fabricate(); $period = AbsencePeriodFabricator::fabricate([ 'start_date' => CRM_Utils_Date::processDate('2016-01-01'), 'end_date' => CRM_Utils_Date::processDate('2016-12-31'), ]); $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ - 'type_id' => 4, + 'type_id' => $absenceType->id, 'contact_id' => 1, 'period_id' => $period->id ]); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveRequestTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveRequestTest.php index 8ecec50ad5a..cf05d7f40cb 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveRequestTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/BAO/LeaveRequestTest.php @@ -65,13 +65,11 @@ public function testALeaveRequestWithSameStartAndEndDateShouldCreateOnlyOneLeave $fromDate = new DateTime(); $date = $fromDate->format('YmdHis'); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, //The status is not important here. We just need a value to be stored in the DB 'from_date' => $date, - 'from_date_type' => 1, - 'to_date' => $date, - 'to_date_type' => 1, + 'to_date' => $date ]); $dates = $leaveRequest->getDates(); @@ -83,13 +81,10 @@ public function testALeaveRequestWithStartAndEndDatesShouldCreateMultipleLeaveRe $fromDate = new DateTime(); $toDate = new DateTime('+3 days'); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, - 'status_id' => 1, //The status is not important here. We just need a value to be stored in the DB 'from_date' => $fromDate->format('YmdHis'), - 'from_date_type' => 1, //The type is not important here. We just need a value to be stored in the DB - 'to_date' => $toDate->format('YmdHis'), - 'to_date_type' => 1 //The type is not important here. We just need a value to be stored in the DB + 'to_date' => $toDate->format('YmdHis') ]); $dates = $leaveRequest->getDates(); @@ -108,9 +103,7 @@ public function testUpdatingALeaveRequestShouldNotDuplicateTheLeaveRequestDates( 'contact_id' => 1, 'status_id' => 1, 'from_date' => $date, - 'from_date_type' => 1, - 'to_date' => $date, - 'to_date_type' => 1 + 'to_date' => $date ]); $dates = $leaveRequest->getDates(); @@ -122,13 +115,12 @@ public function testUpdatingALeaveRequestShouldNotDuplicateTheLeaveRequestDates( $toDate->modify('+1 day'); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $this->absenceType->id, 'id' => $leaveRequest->id, 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'from_date' => $fromDate->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate->format('YmdHis'), - 'to_date_type' => 1, + 'to_date' => $toDate->format('YmdHis') ]); $dates = $leaveRequest->getDates(); @@ -168,9 +160,7 @@ public function testUpdatingALeaveRequestShouldNotThrowOverLappingLeaveRequestEx 'contact_id' => 1, 'status_id' => $leaveRequestStatuses['awaiting_approval'], 'from_date' => CRM_Utils_Date::processDate('2016-11-02'), - 'from_date_type' => 1, - 'to_date' => CRM_Utils_Date::processDate('2016-11-04'), - 'to_date_type' => 1 + 'to_date' => CRM_Utils_Date::processDate('2016-11-04') ], true); //updating leave request @@ -1025,9 +1015,7 @@ public function testAUserCannotCancelOwnLeaveRequestWhenAbsenceTypeDoesNotAllowI 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['awaiting_approval'], 'from_date' => CRM_Utils_Date::processDate('now'), - 'from_date_type' => 1, - 'to_date' => CRM_Utils_Date::processDate('+4 days'), - 'to_date_type' => 1 + 'to_date' => CRM_Utils_Date::processDate('+4 days') ]); $this->setExpectedException('CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', 'Absence Type does not allow leave request cancellation'); @@ -1060,9 +1048,7 @@ public function testAUserCannotCancelOwnLeaveRequestWhenAbsenceTypeAllowsItInAdv 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['awaiting_approval'], 'from_date' => CRM_Utils_Date::processDate('-1 day'), - 'from_date_type' => 1, - 'to_date' => CRM_Utils_Date::processDate('+4 days'), - 'to_date_type' => 1 + 'to_date' => CRM_Utils_Date::processDate('+4 days') ]); $this->setExpectedException('CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', 'Leave Request with past days cannot be cancelled'); @@ -1093,9 +1079,7 @@ public function testFindOverlappingLeaveRequestsForOneOverlappingLeaveRequest() 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate1->format('YmdHis') ], true); LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1103,21 +1087,298 @@ public function testFindOverlappingLeaveRequestsForOneOverlappingLeaveRequest() 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate2->format('YmdHis') ], true); //The start date and end date has dates in only leaveRequest1 $startDate = '2016-11-01'; $endDate = '2016-11-03'; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); $this->assertCount(1, $overlappingRequests); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest1->id, $overlappingRequests[0]->id); } + public function testFindOverlappingLeaveRequestsForHoursUnitRequests() { + $contactID = 1; + + $testFromDate = '2018-04-13 12:00:00'; + $testToDate = '2018-04-15 15:00:00'; + + $absenceTypes = [ + 'days' => AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 1 ]), + 'hours' => AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 2 ]) + ]; + + // Test suites: date from, date to, unit, should overlap or not + $overlappingRequestsTestSuites = [ + ['2018-04-11 00:00:00', '2018-04-12 00:00:00', 'days', FALSE], + ['2018-04-12 00:00:00', '2018-04-13 00:00:00', 'days', TRUE], + ['2018-04-14 00:00:00', '2018-04-14 23:59:00', 'days', TRUE], + ['2018-04-15 23:59:00', '2018-04-16 00:00:00', 'days', TRUE], + ['2018-04-16 00:00:00', '2018-04-17 00:00:00', 'days', FALSE], + ['2018-04-12 00:00:00', '2018-04-13 12:00:00', 'hours', FALSE], + ['2018-04-12 00:00:00', '2018-04-13 14:00:00', 'hours', TRUE], + ['2018-04-12 00:00:00', '2018-04-13 15:00:00', 'hours', TRUE], + ['2018-04-14 00:00:00', '2018-04-15 15:00:00', 'hours', TRUE], + ['2018-04-15 15:00:00', '2018-04-16 00:00:00', 'hours', FALSE] + ]; + + foreach ($overlappingRequestsTestSuites as $overlappingRequestsTestSuite) { + $requestFromDate = new DateTime($overlappingRequestsTestSuite[0]); + $requestToDate = new DateTime($overlappingRequestsTestSuite[1]); + $requestUnit = $overlappingRequestsTestSuite[2]; + $shouldRequestOverlap = $overlappingRequestsTestSuite[3]; + $absenceType = $absenceTypes[$requestUnit]; + + $leaveRequestToTest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'from_date' => $requestFromDate->format('YmdHis'), + 'to_date' => $requestToDate->format('YmdHis'), + ], true); + + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $testFromDate, + 'to_date' => $testToDate, + 'type_id' => $absenceTypes['hours']->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); + $leaveRequestToTestID = $leaveRequestToTest->id; + + // Flush leave request from DB to get ready for the next test suite + $leaveRequestToTest->delete(); + + $this->assertCount($shouldRequestOverlap ? 1 : 0, $overlappingRequests); + if ($shouldRequestOverlap) { + $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); + $this->assertEquals($overlappingRequests[0]->id, $leaveRequestToTestID); + } + } + } + + public function testFindOverlappingLeaveRequestsBetweenTOILAndNonTOILRequests() { + $contactID = 1; + + $testFromDate = '2018-04-13 00:00:00'; + $testToDate = '2018-04-15 23:59:00'; + + $absenceType = AbsenceTypeFabricator::fabricate(); + $absenceTypeForTOILAccrual = AbsenceTypeFabricator::fabricate(['allow_accruals_request' => true]); + + $requestFromDate = new DateTime($testFromDate); + $requestToDate = new DateTime($testToDate); + + foreach ([ + [LeaveRequest::REQUEST_TYPE_LEAVE, LeaveRequest::REQUEST_TYPE_TOIL], + [LeaveRequest::REQUEST_TYPE_TOIL, LeaveRequest::REQUEST_TYPE_LEAVE], + [LeaveRequest::REQUEST_TYPE_SICKNESS, LeaveRequest::REQUEST_TYPE_TOIL], + [LeaveRequest::REQUEST_TYPE_TOIL, LeaveRequest::REQUEST_TYPE_SICKNESS] + ] as $testSuite) { + $existingRequestType = $testSuite[0]; + $testingRequestType = $testSuite[1]; + + $leaveRequestToTest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'request_type' => $existingRequestType, + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'from_date' => $requestFromDate->format('YmdHis'), + 'to_date' => $requestToDate->format('YmdHis') + ]); + + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $testFromDate, + 'to_date' => $testToDate, + 'type_id' => $absenceTypeForTOILAccrual->id, + 'request_type' => $testingRequestType + ]); + + // Flush leave request from DB to get ready for the next test suite + $leaveRequestToTest->delete(); + + $this->assertCount(0, $overlappingRequests); + } + } + + public function testFindOverlappingLeaveRequestsForHalfDayMultipleDayRequests() { + $contactID = 1; + + $testFromDate = '2018-04-13'; + $testToDate = '2018-04-15'; + $halfDayAMID = $this->leaveRequestDayTypes['half_day_am']['value']; + $halfDayPMID = $this->leaveRequestDayTypes['half_day_pm']['value']; + + $absenceType = AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 1 ]); + + // Test suites: date from, date from type, date to, date to type, should overlap or not + $overlappingRequestsTestSuites = [ + ['2018-04-11', 1, '2018-04-13', $halfDayAMID, FALSE], + ['2018-04-11', 1, '2018-04-13', $halfDayPMID, TRUE], + ['2018-04-11', 1, '2018-04-13', 1, TRUE], + ['2018-04-15', 1, '2018-04-17', 1, TRUE], + ['2018-04-15', $halfDayAMID, '2018-04-17', 1, TRUE], + ['2018-04-15', $halfDayPMID, '2018-04-17', 1, FALSE] + ]; + + foreach ($overlappingRequestsTestSuites as $overlappingRequestsTestSuite) { + $requestFromDate = new DateTime($overlappingRequestsTestSuite[0]); + $requestFromDateType = $overlappingRequestsTestSuite[1]; + $requestToDate = new DateTime($overlappingRequestsTestSuite[2]); + $requestToDateType = $overlappingRequestsTestSuite[3]; + $shouldRequestOverlap = $overlappingRequestsTestSuite[4]; + + $leaveRequestToTest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'from_date' => $requestFromDate->format('YmdHis'), + 'from_date_type' => $requestFromDateType, + 'to_date' => $requestToDate->format('YmdHis'), + 'to_date_type' => $requestToDateType + ], true); + + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $testFromDate, + 'from_date_type' => $halfDayPMID, + 'to_date' => $testToDate, + 'to_date_type' => $halfDayAMID, + 'type_id' => $absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); + $leaveRequestToTestID = $leaveRequestToTest->id; + + // Flush leave request from DB to get ready for the next test suite + $leaveRequestToTest->delete(); + + $this->assertCount($shouldRequestOverlap ? 1 : 0, $overlappingRequests); + if ($shouldRequestOverlap) { + $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); + $this->assertEquals($overlappingRequests[0]->id, $leaveRequestToTestID); + } + } + } + + public function testFindOverlappingLeaveRequestsForHalfDaySingleDayRequests() { + $contactID = 1; + $testFromDate = '2018-04-13 00:00:00'; + $testToDate = '2018-04-13 23:59:00'; + $halfDayAMID = $this->leaveRequestDayTypes['half_day_am']['value']; + $halfDayPMID = $this->leaveRequestDayTypes['half_day_pm']['value']; + + $absenceType = AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 1 ]); + + // Test suites: existing request date type, tested request date type, should overlap or not + $overlappingRequestsTestSuites = [ + [$halfDayAMID, $halfDayPMID, FALSE], + [$halfDayAMID, $halfDayAMID, TRUE], + [$halfDayPMID, $halfDayPMID, TRUE], + [$halfDayPMID, $halfDayAMID, FALSE] + ]; + + foreach ($overlappingRequestsTestSuites as $overlappingRequestsTestSuite) { + $requestFromDate = new DateTime($testFromDate); + $requestDateType = $overlappingRequestsTestSuite[0]; + $requestToDate = new DateTime($testToDate); + $testDateType = $overlappingRequestsTestSuite[1]; + $shouldRequestOverlap = $overlappingRequestsTestSuite[2]; + + $leaveRequestToTest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'from_date' => $requestFromDate->format('YmdHis'), + 'from_date_type' => $requestDateType, + 'to_date' => $requestToDate->format('YmdHis'), + 'to_date_type' => $requestDateType + ], true); + + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $testFromDate, + 'from_date_type' => $testDateType, + 'to_date' => $testToDate, + 'to_date_type' => $testDateType, + 'type_id' => $absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); + $leaveRequestToTestID = $leaveRequestToTest->id; + + // Flush leave request from DB to get ready for the next test suite + $leaveRequestToTest->delete(); + + $this->assertCount($shouldRequestOverlap ? 1 : 0, $overlappingRequests); + if ($shouldRequestOverlap) { + $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); + $this->assertEquals($overlappingRequests[0]->id, $leaveRequestToTestID); + } + } + } + + public function testFindOverlappingLeaveRequestsBetweenTOILRequests() { + $contactID = 1; + + $testFromDate = '2018-04-13 10:00:00'; + $testToDate = '2018-04-15 15:00:00'; + + $absenceTypes = [ + 'days' => AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 1 ]), + 'hours' => AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 2 ]) + ]; + + // Test suites: date from, date to, unit, should overlap or not + $overlappingRequestsTestSuites = [ + ['2018-04-11 00:00:00', '2018-04-13 10:00:00', 'days', FALSE], + ['2018-04-11 00:00:00', '2018-04-13 11:00:00', 'days', TRUE], + ['2018-04-15 14:00:00', '2018-04-18 00:00:00', 'days', TRUE], + ['2018-04-15 15:00:00', '2018-04-18 00:00:00', 'days', FALSE], + ['2018-04-11 00:00:00', '2018-04-13 10:00:00', 'hours', FALSE], + ['2018-04-11 00:00:00', '2018-04-13 11:00:00', 'hours', TRUE], + ['2018-04-15 14:00:00', '2018-04-18 00:00:00', 'hours', TRUE], + ['2018-04-15 15:00:00', '2018-04-18 00:00:00', 'hours', FALSE] + ]; + + foreach ($overlappingRequestsTestSuites as $overlappingRequestsTestSuite) { + $requestFromDate = new DateTime($overlappingRequestsTestSuite[0]); + $requestToDate = new DateTime($overlappingRequestsTestSuite[1]); + $absenceType = $absenceTypes[$overlappingRequestsTestSuite[2]]; + $shouldRequestOverlap = $overlappingRequestsTestSuite[3]; + + $leaveRequestToTest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'from_date' => $requestFromDate->format('YmdHis'), + 'to_date' => $requestToDate->format('YmdHis'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], TRUE); + + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $testFromDate, + 'to_date' => $testToDate, + 'type_id' => $absenceTypes['days']->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ]); + $leaveRequestToTestID = $leaveRequestToTest->id; + + // Flush leave request from DB to get ready for the next test suite + $leaveRequestToTest->delete(); + + $this->assertCount($shouldRequestOverlap ? 1 : 0, $overlappingRequests); + if ($shouldRequestOverlap) { + $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); + $this->assertEquals($overlappingRequests[0]->id, $leaveRequestToTestID); + } + } + } + public function testManagerCanCancelOrRejectLeaveRequestEvenIfBalanceIsGreaterThanEntitlementBalanceWhenAllowOveruseFalse() { $manager = ContactFabricator::fabricate(); $staff = ContactFabricator::fabricate(); @@ -1244,9 +1505,7 @@ public function testFindOverlappingLeaveRequestsForMoreThanOneOverlappingLeaveRe 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate1->format('YmdHis') ], true); $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1254,16 +1513,20 @@ public function testFindOverlappingLeaveRequestsForMoreThanOneOverlappingLeaveRe 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 ], true); //The start date and end date has dates in both leave request dates in both leaveRequest1 and leaveRequest2 $startDate = '2016-11-01'; $endDate = '2016-11-06'; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); $this->assertCount(2, $overlappingRequests); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest1->id, $overlappingRequests[0]->id); @@ -1281,9 +1544,7 @@ public function testFindOverlappingLeaveRequestsDoesNotCountSoftDeletedLeaveRequ 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $fromDate->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $fromDate->format('YmdHis') ], true); LeaveRequest::softDelete($leaveRequest->id); @@ -1293,7 +1554,13 @@ public function testFindOverlappingLeaveRequestsDoesNotCountSoftDeletedLeaveRequ $startDate = '2016-11-01'; $endDate = '2016-11-02'; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); $this->assertCount(0, $overlappingRequests); } @@ -1320,9 +1587,7 @@ public function testFindOverlappingLeaveRequestsForMultipleOverlappingLeaveReque 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 ], true); $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1330,16 +1595,20 @@ public function testFindOverlappingLeaveRequestsForMultipleOverlappingLeaveReque 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate2->format('YmdHis') ], true); //The start date and end date has dates in both leave request dates in both leaveRequest1 and leaveRequest2 //public holiday is excluded by default $startDate = '2016-11-01'; $endDate = '2016-11-12'; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]); $this->assertCount(2, $overlappingRequests); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest1->id, $overlappingRequests[0]->id); @@ -1369,9 +1638,7 @@ public function testFindOverlappingLeaveRequestsForMultipleOverlappingLeaveReque 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate1->format('YmdHis') ], true); $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1379,9 +1646,7 @@ public function testFindOverlappingLeaveRequestsForMultipleOverlappingLeaveReque 'contact_id' => $contactID, 'status_id' => 1, 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 ], true); PublicHolidayLeaveRequestFabricator::fabricate($contactID, $publicHoliday); @@ -1391,7 +1656,13 @@ public function testFindOverlappingLeaveRequestsForMultipleOverlappingLeaveReque //leaveRequest2 and public holiday $startDate = '2016-11-01'; $endDate = '2016-11-12'; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate, [], false); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ], [], false); $this->assertCount(3, $overlappingRequests); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest1->id, $overlappingRequests[0]->id); @@ -1427,9 +1698,7 @@ public function testFindOverlappingLeaveRequestsFilteredBySpecificStatusesAndPub 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['awaiting_approval'], 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate1->format('YmdHis') ], true); $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1437,9 +1706,7 @@ public function testFindOverlappingLeaveRequestsFilteredBySpecificStatusesAndPub 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['more_information_required'], 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate2->format('YmdHis') ], true); LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1447,9 +1714,7 @@ public function testFindOverlappingLeaveRequestsFilteredBySpecificStatusesAndPub 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['rejected'], 'from_date' => $fromDate3->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate3->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate3->format('YmdHis') ], true); PublicHolidayLeaveRequestFabricator::fabricate($contactID, $publicHoliday); @@ -1460,7 +1725,13 @@ public function testFindOverlappingLeaveRequestsFilteredBySpecificStatusesAndPub $startDate = '2016-11-02'; $endDate = '2016-11-15'; $filterStatus = [$leaveRequestStatuses['more_information_required']]; - $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate, $filterStatus); + $overlappingRequests = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ], $filterStatus); $this->assertCount(1, $overlappingRequests); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest2->id, $overlappingRequests[0]->id); @@ -1472,7 +1743,13 @@ public function testFindOverlappingLeaveRequestsFilteredBySpecificStatusesAndPub $startDate = '2016-11-01'; $endDate = '2016-11-16'; $filterStatus = [$leaveRequestStatuses['more_information_required'], $leaveRequestStatuses['awaiting_approval']]; - $overlappingRequests2 = LeaveRequest::findOverlappingLeaveRequests($contactID, $startDate, $endDate, $filterStatus, false); + $overlappingRequests2 = LeaveRequest::findOverlappingLeaveRequests([ + 'contact_id' => $contactID, + 'from_date' => $startDate, + 'to_date' => $endDate, + 'type_id' => $this->absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ], $filterStatus, false); $this->assertCount(2, $overlappingRequests2); $this->assertInstanceOf(LeaveRequest::class, $overlappingRequests[0]); $this->assertEquals($leaveRequest1->id, $overlappingRequests2[0]->id); @@ -1504,9 +1781,7 @@ public function testALeaveRequestShouldNotBeCreatedWhenThereAreOverlappingLeaveR 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['awaiting_approval'], 'from_date' => $fromDate1->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate1->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate1->format('YmdHis') ], true); LeaveRequestFabricator::fabricateWithoutValidation([ @@ -1514,9 +1789,7 @@ public function testALeaveRequestShouldNotBeCreatedWhenThereAreOverlappingLeaveR 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['rejected'], 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate2->format('YmdHis') ], true); //from date and to date have date in both leave request @@ -1535,6 +1808,108 @@ public function testALeaveRequestShouldNotBeCreatedWhenThereAreOverlappingLeaveR ]); } + public function testLeaveRequestInDaysPMCannotNotBeCreatedAfterLeaveRequestInHoursWasCreatedForTheSameDay() { + $contactId = 1; + $date = '2018-05-07'; + $absenceTypeInDays = AbsenceTypeFabricator::fabricate(); + $absenceTypeInHours = AbsenceTypeFabricator::fabricate(['calculation_unit' => 2]); + $leaveRequestStatuses = array_flip(LeaveRequest::buildOptions('status_id', 'validate')); + $halfDayPMId = $this->leaveRequestDayTypes['half_day_pm']['value']; + + $period = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31') + ]); + + $periodEntitlemenInHours = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'period_id' => $period->id + ]); + + $periodEntitlemenInDays = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'period_id' => $period->id + ]); + + $this->createLeaveBalanceChange($periodEntitlemenInHours->id, 100); + $this->createLeaveBalanceChange($periodEntitlemenInDays->id, 100); + + $leaveRequest1 = LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 09:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date. ' 10:00:00') + ], true); + + $this->setExpectedException( + 'CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', + 'This leave request overlaps with another request. Please modify dates of this request' + ); + + $leaveRequest2 = LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date), + 'from_date_type' => $halfDayPMId, + 'to_date_type' => $halfDayPMId + ], true); + } + + public function testTOILRequestInHoursCanBeCreatedAfterTOILRequestInDaysWasCreatedForTheSameDay() { + $contactId = 1; + $date = '2018-05-07'; + $absenceTypeInDays = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => true + ]); + $absenceTypeInHours = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => true, + 'calculation_unit' => 2 + ]); + $leaveRequestStatuses = array_flip(LeaveRequest::buildOptions('status_id', 'validate')); + + $period = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31') + ]); + + $periodEntitlemenInHours = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'period_id' => $period->id + ]); + + $periodEntitlemenInDays = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'period_id' => $period->id + ]); + + $leaveRequest1 = LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 09:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date. ' 10:00:00'), + 'toil_duration' => 1, + 'toil_to_accrue' => 1, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], true); + + $leaveRequest2 = LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 11:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date. ' 12:00:00'), + 'toil_duration' => 1, + 'toil_to_accrue' => 1, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ], true); + } + public function testLeaveRequestCanBeCreatedWhenThereIsAnOverlappingPublicHolidayLeaveRequest() { $contactID = 1; $publicHoliday = new PublicHoliday(); @@ -1620,9 +1995,7 @@ public function testLeaveRequestCanBeCreatedWhenThereAreNoOverlappingLeaveReques 'contact_id' => $contactID, 'status_id' => $leaveRequestStatuses['rejected'], 'from_date' => $fromDate2->format('YmdHis'), - 'from_date_type' => 1, - 'to_date' => $toDate2->format('YmdHis'), - 'to_date_type' => 1 + 'to_date' => $toDate2->format('YmdHis') ], true); //this date overlaps with a Rejected status leave request @@ -2567,6 +2940,50 @@ public function testLeaveRequestCanNotBeCreatedWhenRequestTypeIsToilAndDatesAreI ]); } + public function testLeaveRequestCanBeCancelledWhenRequestTypeIsToilAndDatesAreInThePastAndAbsenceTypeDoesNotAllowPastAccrual() { + $leaveRequestStatuses = LeaveRequest::getStatuses(); + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2017-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2017-06-14'), + ]); + + WorkPatternFabricator::fabricateWithA40HourWorkWeek(['is_default' => 1]); + $contactID = 1; + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactID], + ['period_start_date' => '2017-01-01'] + ); + + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => false + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'period_id' => $absencePeriod->id + ]); + + $params = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'status_id' => $leaveRequestStatuses['cancelled'], + 'from_date' => CRM_Utils_Date::processDate('2017-02-01'), + 'to_date' => CRM_Utils_Date::processDate('2017-02-05'), + 'from_date_type' => 1, + 'to_date_type' => 1, + 'toil_to_accrue' => 3, + 'toil_duration' => 120, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ]; + + $this->createLeaveBalanceChange($periodEntitlement->id, 10); + $toilRequest = LeaveRequest::create($params); + $this->assertNotNull($toilRequest->id); + } + public function testLeaveRequestCanNotBeCreatedWhenRequestTypeIsToilAndToilToAccrueIsGreaterThanTheMaximumAllowed() { AbsencePeriodFabricator::fabricate([ 'start_date' => CRM_Utils_Date::processDate('today'), @@ -2803,8 +3220,8 @@ public function testDeleteAllNonExpiredTOILRequestsForAbsenceType() { public function testFindByIdThrowsAnExceptionWhenFindingASoftDeletedLeaveRequest() { $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $this->absenceType->id, 'contact_id' => 1, - 'type_id' => 1, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-02'), 'status_id' => 1 @@ -2818,8 +3235,8 @@ public function testFindByIdThrowsAnExceptionWhenFindingASoftDeletedLeaveRequest public function testFindByIdThrowsAnExceptionWhenFindingADeletedLeaveRequest() { $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $this->absenceType->id, 'contact_id' => 1, - 'type_id' => 1, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-02'), 'status_id' => 1 @@ -2854,11 +3271,9 @@ public function testValidateParamsThrowsAnExceptionWhenTryingToChangeIsDeletedVa public function testLeaveRequestIsDeletedValueCanNotBeSetWhenCreatingALeaveRequest() { $params = [ + 'type_id' => $this->absenceType->id, 'contact_id' => 1, - 'type_id' => 1, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), - 'from_date_type' => 1, - 'to_date_type' => 1, 'to_date' => CRM_Utils_Date::processDate('2016-01-02'), 'status_id' => 1, 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE, @@ -2890,9 +3305,7 @@ public function testEmailGetsSentWhenLeaveRequestIsCreatedAndUpdated() { 'contact_id' => $leaveContact['id'], 'status_id' => 1, 'from_date' => CRM_Utils_Date::processDate('tomorrow'), - 'from_date_type' => 1, 'to_date' => CRM_Utils_Date::processDate('tomorrow'), - 'to_date_type' => 1, 'toil_to_accrue' => 2, 'toil_duration' => 120, 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE @@ -3002,9 +3415,12 @@ public function testToilCanBeAccruedWhenTheCurrentBalanceForPeriodEntitlementIsZ } public function testToilCanBeAccruedWhenTheToilRequestHasNoWorkingDay() { + $dateSaturday = CRM_Utils_Date::processDate('2018-05-05'); + $dateSunday = CRM_Utils_Date::processDate('2018-05-06'); + $period = AbsencePeriodFabricator::fabricate([ - 'start_date' => CRM_Utils_Date::processDate('-1 day'), - 'end_date' => CRM_Utils_Date::processDate('+10 days'), + 'start_date' => $dateSaturday, + 'end_date' => $dateSunday, ]); $absenceType = AbsenceTypeFabricator::fabricate([ @@ -3037,9 +3453,9 @@ public function testToilCanBeAccruedWhenTheToilRequestHasNoWorkingDay() { 'type_id' => $absenceType->id, 'contact_id' => $periodEntitlement->contact_id, 'status_id' => 1, - 'from_date' => CRM_Utils_Date::processDate('saturday'), + 'from_date' => $dateSaturday, 'from_date_type' => 1, - 'to_date' => CRM_Utils_Date::processDate('sunday'), + 'to_date' => $dateSunday, 'to_date_type' => 1, 'toil_to_accrue' => 2.5, 'toil_duration' => 120, @@ -3095,8 +3511,8 @@ public function testToilToAccrueAmountIsSavedCorrectlyWhenAmountToAccrueIsAFloat $toilToAccrueAmounts = [1.5, 1.8, 2.5]; foreach ($toilToAccrueAmounts as $toilToAccrueAmount) { LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => $this->absenceType->id, 'contact_id' => 1, - 'type_id' => 1, 'toil_to_accrue'=> $toilToAccrueAmount, 'from_date' => CRM_Utils_Date::processDate('yesterday'), 'to_date' => CRM_Utils_Date::processDate('today'), @@ -3150,8 +3566,6 @@ public function testUpdatingToilThrowsExceptionWhenUpdatingApprovedToilWithAToil 'from_date' => CRM_Utils_Date::processDate('monday'), 'to_date' => CRM_Utils_Date::processDate('monday'), 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, - 'from_date_type' => 1, - 'to_date_type' => 1, 'toil_duration' => 60 ]; @@ -3209,8 +3623,6 @@ public function testToilCanBeAccruedWhenUpdatingApprovedToilWithAToilAmountGreat 'from_date' => CRM_Utils_Date::processDate('monday'), 'to_date' => CRM_Utils_Date::processDate('monday'), 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, - 'from_date_type' => 1, - 'to_date_type' => 1, 'toil_duration' => 60 ]; @@ -3266,8 +3678,6 @@ public function testToilCanBeAccruedWhenUpdatingApprovedToilWithAToilAmountLesse 'from_date' => CRM_Utils_Date::processDate('monday'), 'to_date' => CRM_Utils_Date::processDate('monday'), 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, - 'from_date_type' => 1, - 'to_date_type' => 1, 'toil_duration' => 60 ]; @@ -3323,8 +3733,6 @@ public function testToilCanBeAccruedWhenUpdatingApprovedToilWithAToilAmountSameA 'from_date' => CRM_Utils_Date::processDate('monday'), 'to_date' => CRM_Utils_Date::processDate('monday'), 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, - 'from_date_type' => 1, - 'to_date_type' => 1, 'toil_duration' => 60 ]; @@ -3393,8 +3801,6 @@ public function testUpdatingToilThrowsExceptionWhenUpdatingApprovedToilWithDates 'from_date' => CRM_Utils_Date::processDate('2016-01-06'), 'to_date' => CRM_Utils_Date::processDate('2016-01-06'), 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, - 'from_date_type' => 1, - 'to_date_type' => 1, 'toil_duration' => 60 ]; @@ -3446,9 +3852,7 @@ public function testLeaveDatesAreNotDeletedAndRecreatedWhenUpdatingALeaveRequest 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3475,13 +3879,11 @@ public function testDatesChangedReturnsTrueWhenOnlyFromDateTypeChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3497,13 +3899,11 @@ public function testDatesChangedReturnsTrueWhenOnlyToDateTypeChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3519,13 +3919,11 @@ public function testDatesChangedReturnsTrueWhenOnlyToDateChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3541,13 +3939,11 @@ public function testDatesChangedReturnsTrueWhenOnlyFromDateChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3563,13 +3959,11 @@ public function testDatesChangedReturnsTrueWhenAllTheDateParameterChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3588,13 +3982,11 @@ public function testDatesChangedReturnsTrueWhenOnlyToDateAndToDateTypeChanges(){ $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3611,13 +4003,11 @@ public function testDatesChangedReturnsTrueWhenOnlyFromDateAndFromDateTypeChange $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, - 'from_date_type' => 1, - 'to_date' => $toDate, - 'to_date_type' => 1, + 'to_date' => $toDate ]; $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); @@ -3634,7 +4024,7 @@ public function testDatesChangedReturnsFalseWhenAllTheDateParameterDoesNotChange $fromDate = CRM_Utils_Date::processDate('2016-01-08'); $toDate = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => $fromDate, @@ -3743,7 +4133,7 @@ public function testLeaveRequestBeCreatedWhenLeaveRequestHasNoWorkingDayAndValid 'period_id' => $period->id ]); - $this->createLeaveBalanceChange($periodEntitlement->id, 3); + $this->createLeaveBalanceChange($periodEntitlement->id, 100); HRJobContractFabricator::fabricate( ['contact_id' => $periodEntitlement->contact_id], @@ -3767,6 +4157,363 @@ public function testLeaveRequestBeCreatedWhenLeaveRequestHasNoWorkingDayAndValid $this->assertNotNull($leaveRequest->id); } + public function testMultipleLeaveRequestsInHoursCanNotBeCreatedForTheSameDayIfTheirTimeIntersect() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 2 ]); + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + $this->createLeaveBalanceChange($periodEntitlement->id, 100); + + $params = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 01:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date . ' 03:00:00') + ]; + + $leaveRequest1 = LeaveRequestFabricator::fabricate($params, true); + + $params['from_date'] = CRM_Utils_Date::processDate($date . ' 02:00:00'); + $params['to_date'] = CRM_Utils_Date::processDate($date . ' 04:00:00'); + + $this->setExpectedException( + 'CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', + 'This leave request overlaps with another request. Please modify dates of this request' + ); + + $leaveRequest2 = LeaveRequestFabricator::fabricate($params, true); + } + + public function testMultipleLeaveRequestsInHoursCanBeCreatedForTheSameDayIfTheirTimeDoNotIntersect() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate([ 'calculation_unit' => 2 ]); + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + $this->createLeaveBalanceChange($periodEntitlement->id, 3); + + $params = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 01:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date . ' 03:00:00') + ]; + + $leaveRequest1 = LeaveRequestFabricator::fabricate($params, true); + + $params['from_date'] = CRM_Utils_Date::processDate($date . ' 03:00:00'); + $params['to_date'] = CRM_Utils_Date::processDate($date . ' 05:00:00'); + + $leaveRequest2 = LeaveRequestFabricator::fabricate($params, true); + + $this->assertNotNull($leaveRequest1->id); + $this->assertNotNull($leaveRequest2->id); + } + + public function testTOILAccrualAndLeaveRequestCanBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceTypeLeave = AbsenceTypeFabricator::fabricate(); + $absenceTypeTOIL = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => true + ]); + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlementLeave = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeLeave->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + $periodEntitlementTOIL = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeTOIL->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlementLeave->id, 3); + $this->createLeaveBalanceChange($periodEntitlementTOIL->id, 3); + + $params = [ + 'type_id' => $absenceTypeLeave->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date) + ]; + + $leaveRequest1 = LeaveRequestFabricator::fabricate($params, true); + + $params['request_type'] = LeaveRequest::REQUEST_TYPE_TOIL; + $params['type_id'] = $absenceTypeTOIL->id; + + $leaveRequest2 = LeaveRequestFabricator::fabricate($params, true); + + $this->assertNotNull($leaveRequest1->id); + $this->assertNotNull($leaveRequest2->id); + } + + public function testTwoLeaveRequestsOneAMAndAnotherPMCanBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate(); + $halfDayAMID = $this->leaveRequestDayTypes['half_day_am']['value']; + $halfDayPMID = $this->leaveRequestDayTypes['half_day_pm']['value']; + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlement->id, 3); + + $params = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date), + 'from_date_type' => $halfDayAMID, + 'to_date_type' => $halfDayAMID + ]; + + $leaveRequest1 = LeaveRequestFabricator::fabricate($params, true); + + $params['from_date_type'] = $halfDayPMID; + $params['to_date_type'] = $halfDayPMID; + + $leaveRequest2 = LeaveRequestFabricator::fabricate($params, true); + + $this->assertNotNull($leaveRequest1->id); + $this->assertNotNull($leaveRequest2->id); + } + + public function testTwoTOILRequestsCanBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => true, + 'calculation_unit' => 2 + ]); + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlement->id, 100); + + $params = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 10:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date . ' 10:15:00'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + 'toil_to_accrue' => 2 + ]; + + $leaveRequest1 = LeaveRequestFabricator::fabricate($params, true); + + $params['from_date'] = CRM_Utils_Date::processDate($date . ' 11:00:00'); + $params['to_date'] = CRM_Utils_Date::processDate($date . ' 11:15:00'); + + $leaveRequest2 = LeaveRequestFabricator::fabricate($params, true); + + $this->assertNotNull($leaveRequest1->id); + $this->assertNotNull($leaveRequest2->id); + } + + public function testTwoLeaveRequestsBothForAMCannotBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate(); + $halfDayAMID = $this->leaveRequestDayTypes['half_day_am']['value']; + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlement->id, 100); + + $leaveRequestParams = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date), + 'from_date_type' => $halfDayAMID, + 'to_date_type' => $halfDayAMID + ]; + + LeaveRequestFabricator::fabricate($leaveRequestParams, true); + + $this->setExpectedException( + 'CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', + 'This leave request overlaps with another request. Please modify dates of this request' + ); + + LeaveRequestFabricator::fabricate($leaveRequestParams, true); + } + + public function testTwoLeaveRequestsBothForPMCannotBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceType = AbsenceTypeFabricator::fabricate(); + $halfDayPMID = $this->leaveRequestDayTypes['half_day_pm']['value']; + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlement->id, 100); + + $leaveRequestParams = [ + 'type_id' => $absenceType->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date), + 'from_date_type' => $halfDayPMID, + 'to_date_type' => $halfDayPMID + ]; + + LeaveRequestFabricator::fabricate($leaveRequestParams, true); + + $this->setExpectedException( + 'CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', + 'This leave request overlaps with another request. Please modify dates of this request' + ); + + LeaveRequestFabricator::fabricate($leaveRequestParams, true); + } + + public function testTwoLeaveRequestsOneInDaysAndAnotherInHoursCannotBeCreatedForTheSameDay() { + $date = '2018-04-13'; + $contactId = 1; + $absenceTypeInDays = AbsenceTypeFabricator::fabricate(); + $absenceTypeInHours = AbsenceTypeFabricator::fabricate(['calculation_unit' => 2]); + $halfDayAMID = $this->leaveRequestDayTypes['half_day_am']['value']; + + $absencePeriod = AbsencePeriodFabricator::fabricate([ + 'start_date' => CRM_Utils_Date::processDate('2018-01-01'), + 'end_date' => CRM_Utils_Date::processDate('2018-12-31'), + ]); + + $periodEntitlementInDays = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + $periodEntitlementInHours = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'period_id' => $absencePeriod->id + ]); + + HRJobContractFabricator::fabricate( + ['contact_id' => $contactId], + ['period_start_date' => CRM_Utils_Date::processDate('2018-01-01')] + ); + + $this->createLeaveBalanceChange($periodEntitlementInDays->id, 100); + $this->createLeaveBalanceChange($periodEntitlementInHours->id, 100); + + LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInDays->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date), + 'to_date' => CRM_Utils_Date::processDate($date), + 'from_date_type' => $halfDayAMID, + 'to_date_type' => $halfDayAMID + ], true); + + $this->setExpectedException( + 'CRM_HRLeaveAndAbsences_Exception_InvalidLeaveRequestException', + 'This leave request overlaps with another request. Please modify dates of this request' + ); + + LeaveRequestFabricator::fabricate([ + 'type_id' => $absenceTypeInHours->id, + 'contact_id' => $contactId, + 'from_date' => CRM_Utils_Date::processDate($date . ' 23:00:00'), + 'to_date' => CRM_Utils_Date::processDate($date . ' 23:15:00') + ], true); + } + public function testAnAlreadyApprovedLeaveRequestCanBeUpdatedWhenEntitlementBalanceIsZero() { $period = AbsencePeriodFabricator::fabricate([ 'start_date' => CRM_Utils_Date::processDate('2016-01-01'), @@ -4237,7 +4984,7 @@ public function testAnAlreadyApprovedLeaveRequestCanNotBeUpdatedWhenEntitlementB public function testToilToAccrueChangedReturnsTrueWhenToilToAccrueChanges(){ $date = CRM_Utils_Date::processDate('2016-01-10'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'from_date' => $date, 'to_date' => $date, @@ -4257,7 +5004,7 @@ public function testToilToAccrueChangedReturnsTrueWhenToilToAccrueChanges(){ public function testToilToAccrueChangedReturnsFalseWhenToilToAccrueDoesNotChange(){ $date = CRM_Utils_Date::processDate('2016-01-08'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'from_date' => $date, 'to_date' => $date, @@ -4276,7 +5023,7 @@ public function testToilToAccrueChangedReturnsFalseWhenToilToAccrueDoesNotChange public function testToilToAccrueChangedReturnsNullWhenRequestTypeIsNotToil(){ $date = CRM_Utils_Date::processDate('2016-01-08'); $params = [ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'from_date' => $date, 'to_date' => $date, @@ -4294,7 +5041,6 @@ public function testToilToAccrueChangedReturnsNullWhenRequestTypeIsNotToil(){ public function testToilToAccrueChangedReturnsNullWhenCreatingANewRequest(){ $date = CRM_Utils_Date::processDate('2016-01-08'); $params = [ - 'type_id' => 1, 'contact_id' => 1, 'from_date' => $date, 'to_date' => $date, @@ -4554,4 +5300,44 @@ public function testNonMandatoryFieldsAreResetWhenAbsenceTypeChangedToOneWithADi $this->assertEquals($leaveRequestParams['from_date_type'], $leaveRequest->from_date_type); $this->assertEquals($leaveRequestParams['to_date_type'], $leaveRequest->to_date_type); } + + public function testisTOILWithPastDatesReturnsFalseWhenRequestTypeIsNotTOIL() { + $params = [ + 'from_date' => '2020-01-01', + 'to_date' => '2025-01-02', + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE + ]; + + $this->assertFalse(LeaveRequest::isTOILWithPastDates($params)); + } + + public function testisTOILWithPastDatesReturnsTrueWhenFromDateIsLessThanToday() { + $params = [ + 'from_date' => '2017-01-01', + 'to_date' => '2025-01-02', + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ]; + + $this->assertTrue(LeaveRequest::isTOILWithPastDates($params)); + } + + public function testisTOILWithPastDatesReturnsTrueWhenToDateIsLessThanToday() { + $params = [ + 'from_date' => '2025-01-01', + 'to_date' => '2017-01-02', + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ]; + + $this->assertTrue(LeaveRequest::isTOILWithPastDates($params)); + } + + public function testisTOILWithPastDatesReturnsFalseWhenToDateAndFromDateIsGreaterThanToday() { + $params = [ + 'from_date' => '2025-01-01', + 'to_date' => '2025-01-02', + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL + ]; + + $this->assertFalse(LeaveRequest::isTOILWithPastDates($params)); + } } diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Mail/MessageTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Mail/MessageTest.php index 8a2e368dd1a..9f34fc0cfb9 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Mail/MessageTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Mail/MessageTest.php @@ -17,6 +17,7 @@ class CRM_HRLeaveAndAbsences_Mail_MessageTest extends BaseHeadlessTest { use CRM_HRLeaveAndAbsences_LeaveManagerHelpersTrait; use CRM_HRLeaveAndAbsences_MailHelpersTrait; + use CRM_HRLeaveAndAbsences_SessionHelpersTrait; private $leaveRequestTemplateFactory; @@ -264,6 +265,77 @@ public function testGetTemplateIDReturnsNullWhenThereIsNoTemplateForARequestType $this->assertNull($message->getTemplateID()); } + public function testGetRecipientEmailsWillNotIncludeEmailOfLeaveContactIfLoggedIn() { + $managerEmail = 'manager1@dummysite.com'; + $manager = ContactFabricator::fabricateWithEmail([ + 'first_name' => 'Manager1', 'last_name' => 'Manager1'], $managerEmail + ); + + $managerService = $this->prophesize(LeaveManagerService::class); + $returnValue = [ + $manager['id'] => $manager['first_name'], + ]; + // Set manager to be leave aprover for the leave contact + $managerService->getLeaveApproversForContact($this->leaveContact['id'])->willReturn($returnValue); + + //register the leave contact in session + $this->registerCurrentLoggedInContactInSession($this->leaveContact['id']); + + $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => 1, + 'contact_id' => $this->leaveContact['id'], + 'from_date' => CRM_Utils_Date::processDate('tomorrow'), + 'to_date' => CRM_Utils_Date::processDate('tomorrow'), + ], FALSE); + + $message = new Message($leaveRequest, $this->leaveRequestTemplateFactory, $managerService->reveal()); + + $recipientEmails = array_column($message->getRecipientEmails(), 'email'); + + //Since the leave contact is the logged in contact making the change to the leave request. + //the leave contact email will not be included. + $this->assertCount(1, $recipientEmails); + + $this->assertEquals([$managerEmail], $recipientEmails); + $this->unregisterCurrentLoggedInContactFromSession($this->leaveContact['id']); + } + + public function testGetRecipientEmailsWillNotIncludeEmailOfLeaveManagerIfLoggedIn() { + $manager = ContactFabricator::fabricateWithEmail([ + 'first_name' => 'Manager1', 'last_name' => 'Manager1'], 'manager1@dummysite.com' + ); + + $managerService = $this->prophesize(LeaveManagerService::class); + $returnValue = [ + $manager['id'] => $manager['first_name'], + ]; + // Set manager to be leave aprovers for the leave contact + $managerService->getLeaveApproversForContact($this->leaveContact['id'])->willReturn($returnValue); + + //register the leave manager in session + $this->registerCurrentLoggedInContactInSession($manager['id']); + + $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ + 'type_id' => 1, + 'contact_id' => $this->leaveContact['id'], + 'from_date' => CRM_Utils_Date::processDate('tomorrow'), + 'to_date' => CRM_Utils_Date::processDate('tomorrow'), + ], FALSE); + + $message = new Message($leaveRequest, $this->leaveRequestTemplateFactory, $managerService->reveal()); + + $recipientEmails = array_column($message->getRecipientEmails($manager['id']), 'email'); + + //Since the manager is the logged in contact making the change to the leave request. + //the leave manager email will not be included. + $this->assertCount(1, $recipientEmails); + + $expectedEmails = ['staffmember@dummysite.com']; + $this->assertEquals($expectedEmails, $recipientEmails); + $this->unregisterCurrentLoggedInContactFromSession($manager['id']); + } + + private function getManagerService() { $managerService = $this->prophesize(LeaveManagerService::class); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestRightsTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestRightsTest.php index b2beb3b0366..a31f39d90ed 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestRightsTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestRightsTest.php @@ -2,6 +2,7 @@ use CRM_HRLeaveAndAbsences_Service_LeaveRequestRights as LeaveRequestRightsService; use CRM_HRLeaveAndAbsences_BAO_LeaveRequest as LeaveRequest; +use CRM_HRLeaveAndAbsences_Test_Fabricator_AbsenceType as AbsenceTypeFabricator; /** * Class CRM_HRLeaveAndAbsences_Service_LeaveRequestRightsTest @@ -220,17 +221,77 @@ public function testCanChangeAbsenceTypeForReturnsFalseWhenCurrentUserNotLeaveCo ); } - private function getLeaveRightsService($isAdmin = false, $isManager = false) { + public function testCanCancelToilWithPastDatesReturnsTrueWhenCurrentUserIsManagerAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => FALSE + ]); + + $leaveRightsService = $this->getLeaveRequestRightsForLeaveManagerAsCurrentUser(); + $this->assertTrue($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + public function testCanCancelToilWithPastDatesReturnsTrueWhenCurrentUserIsAdminAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => FALSE + ]); + + $leaveRightsService = $this->getLeaveRequestRightsForAdminAsCurrentUser(); + $this->assertTrue($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + public function testCanCancelToilWithPastDatesReturnsFalseWhenCurrentUserIsLeaveContactAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => FALSE + ]); + + $leaveRightsService = $this->getLeaveRightsService(); + $this->assertFalse($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + public function testCanCancelToilWithPastDatesReturnsTrueWhenAbsenceTypeAllowsPastAccrualForLeaveContact() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => TRUE + ]); + + $leaveRightsService = $this->getLeaveRightsService(); + $this->assertTrue($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + public function testCanCancelToilWithPastDatesReturnsTrueWhenAbsenceTypeAllowsPastAccrualForAdmin() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => TRUE + ]); + + $leaveRightsService = $this->getLeaveRequestRightsForAdminAsCurrentUser(); + $this->assertTrue($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + public function testCanCancelToilWithPastDatesReturnsTrueWhenAbsenceTypeAllowsPastAccrualForManager() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => TRUE, + 'allow_accrue_in_the_past' => TRUE + ]); + + $leaveRightsService = $this->getLeaveRequestRightsForLeaveManagerAsCurrentUser(); + $this->assertTrue($leaveRightsService->canCancelToilWithPastDates($this->leaveContact, $absenceType->id)); + } + + private function getLeaveRightsService($isAdmin = FALSE, $isManager = FALSE) { $leaveManagerService = $this->createLeaveManagerServiceMock($isAdmin, $isManager); return new LeaveRequestRightsService($leaveManagerService); } private function getLeaveRequestRightsForAdminAsCurrentUser() { - return $this->getLeaveRightsService(true, false); + return $this->getLeaveRightsService(TRUE, FALSE); } private function getLeaveRequestRightsForLeaveManagerAsCurrentUser() { - return $this->getLeaveRightsService(false, true); + return $this->getLeaveRightsService(FALSE, TRUE); } public function leaveRequestStatusesDataProvider() { diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestTest.php index 1535c2d653b..434b03428ba 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/CRM/HRLeaveAndAbsences/Service/LeaveRequestTest.php @@ -1098,6 +1098,126 @@ public function testGetBreakdownIncludeOnlyTheLeaveBalanceChangesOfTheLeaveReque $this->assertEquals($expectedBreakdown, $breakdown); } + public function testToilRequestWithPastDatesCanNotBeCancelledWhenUserIsLeaveContactAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => false + ]); + + $leaveStatuses = LeaveRequest::getStatuses(); + $toilParams = [ + 'from_date' => CRM_Utils_Date::processDate('2016-01-04'), + 'to_date' => CRM_Utils_Date::processDate('2016-01-07'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + 'toil_to_accrue' => 1, + 'type_id' => $absenceType->id, + 'status_id' => $leaveStatuses['approved'] + ]; + + $params = $this->getDefaultParams($toilParams); + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); + + //Update the toil status to cancelled. + $params['status_id'] = $leaveStatuses['cancelled']; + $params['id'] = $toilRequest->id; + + $this->setExpectedException('RuntimeException', 'You may only cancel TOIL with dates in the future.'); + $this->getLeaveRequestService()->create($params, false); + } + + public function testToilRequestWithPastDatesCanBeCancelledWhenUserIsAdminAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => false + ]); + + $leaveStatuses = LeaveRequest::getStatuses(); + $toilParams = [ + 'from_date' => CRM_Utils_Date::processDate('2016-01-04'), + 'to_date' => CRM_Utils_Date::processDate('2016-01-07'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + 'toil_to_accrue' => 1, + 'type_id' => $absenceType->id, + 'status_id' => $leaveStatuses['approved'] + ]; + + $params = $this->getDefaultParams($toilParams); + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); + + //Update the toil status to cancelled. + $params['status_id'] = $leaveStatuses['cancelled']; + $params['id'] = $toilRequest->id; + + $toilRequest = $this->getLeaveRequestServiceWhenCurrentUserIsAdmin()->create($params, false); + + $this->assertNotNull($toilRequest->id); + $this->assertEquals($toilRequest->status_id, $leaveStatuses['cancelled']); + } + + public function testToilRequestWithPastDatesCanBeCancelledWhenUserIsManagerAndAbsenceTypeDoesNotAllowPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => false + ]); + + $leaveStatuses = LeaveRequest::getStatuses(); + $toilParams = [ + 'from_date' => CRM_Utils_Date::processDate('2016-01-04'), + 'to_date' => CRM_Utils_Date::processDate('2016-01-07'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + 'toil_to_accrue' => 1, + 'type_id' => $absenceType->id, + 'status_id' => $leaveStatuses['approved'] + ]; + + $params = $this->getDefaultParams($toilParams); + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); + + //Update the toil status to cancelled. + $params['status_id'] = $leaveStatuses['cancelled']; + $params['id'] = $toilRequest->id; + + $toilRequest = $this->getLeaveRequestServiceWhenCurrentUserIsLeaveManager()->create( + $params, + false + ); + + $this->assertNotNull($toilRequest->id); + $this->assertEquals($toilRequest->status_id, $leaveStatuses['cancelled']); + } + + public function testToilRequestWithPastDatesCanBeCancelledWhenAbsenceTypeAllowsPastAccrual() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'allow_accrue_in_the_past' => true + ]); + + $leaveStatuses = LeaveRequest::getStatuses(); + $toilParams = [ + 'from_date' => CRM_Utils_Date::processDate('2016-01-04'), + 'to_date' => CRM_Utils_Date::processDate('2016-01-07'), + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + 'toil_to_accrue' => 1, + 'type_id' => $absenceType->id, + 'status_id' => $leaveStatuses['approved'] + ]; + + $params = $this->getDefaultParams($toilParams); + $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation($params); + + //Update the toil status to cancelled. + $params['status_id'] = $leaveStatuses['cancelled']; + $params['id'] = $toilRequest->id; + + $toilRequest = $this->getLeaveRequestService()->create( + $params, + false + ); + + $this->assertNotNull($toilRequest->id); + $this->assertEquals($toilRequest->status_id, $leaveStatuses['cancelled']); + } + private function getExpectedBreakdownForLeaveRequest(LeaveRequest $leaveRequest, $amount = false) { $leaveRequestDayTypes = LeaveRequest::buildOptions('from_date_type'); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/api/v3/LeaveRequestTest.php b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/api/v3/LeaveRequestTest.php index aab38d5e4ea..828de26388d 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/api/v3/LeaveRequestTest.php +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/tests/phpunit/api/v3/LeaveRequestTest.php @@ -194,7 +194,7 @@ public function testGetBalanceChangeByAbsenceTypeCanBeFilteredByStatuses() { $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ 'contact_id' => 1, 'period_id' => $absencePeriod->id, - 'type_id' => 1 + 'type_id' => $this->absenceType->id ]); HRJobContractFabricator::fabricate( @@ -656,7 +656,7 @@ public function testGetCanReturnALeaveRequestWhichOverlapsAContractWithoutEndDat //This leave request is before the contract start date and will not be returned LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2015-12-30'), 'to_date' => CRM_Utils_Date::processDate('2015-12-31'), 'status_id' => $leaveRequestStatuses['awaiting_approval'] @@ -665,7 +665,7 @@ public function testGetCanReturnALeaveRequestWhichOverlapsAContractWithoutEndDat //This will be returned as it is after the contract start date $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2017-12-30'), 'to_date' => CRM_Utils_Date::processDate('2017-12-31'), 'status_id' => $leaveRequestStatuses['awaiting_approval'] @@ -690,7 +690,7 @@ public function testGetCanReturnLeaveRequestsWhichOverlapAContractWithEndDate() //This leave request is before the contract start date and will not be returned LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2015-12-30'), 'to_date' => CRM_Utils_Date::processDate('2015-12-31'), 'status_id' => $leaveRequestStatuses['awaiting_approval'] @@ -699,7 +699,7 @@ public function testGetCanReturnLeaveRequestsWhichOverlapAContractWithEndDate() // This will be returned $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-02'), 'to_date' => CRM_Utils_Date::processDate('2016-01-03'), 'status_id' => $leaveRequestStatuses['approved'] @@ -708,7 +708,7 @@ public function testGetCanReturnLeaveRequestsWhichOverlapAContractWithEndDate() // This will be returned $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-09-07'), 'to_date' => CRM_Utils_Date::processDate('2016-09-08'), 'status_id' => $leaveRequestStatuses['approved'] @@ -717,7 +717,7 @@ public function testGetCanReturnLeaveRequestsWhichOverlapAContractWithEndDate() //This will not be returned as it is after the contract start date LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2017-12-30'), 'to_date' => CRM_Utils_Date::processDate('2017-12-31'), 'status_id' => $leaveRequestStatuses['awaiting_approval'] @@ -737,7 +737,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW //This leave request is before the contract start date and will not be returned LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2015-12-30'), 'to_date' => CRM_Utils_Date::processDate('2015-12-30'), 'from_date_type' => 1, @@ -748,7 +748,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW // This will be returned as it's after the contract start date $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2017-09-02'), 'to_date' => CRM_Utils_Date::processDate('2017-09-02'), 'from_date_type' => 1, @@ -759,7 +759,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW // This will be returned as it's after the contract start date as well $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2018-01-02'), 'to_date' => CRM_Utils_Date::processDate('2018-01-02'), 'from_date_type' => 1, @@ -787,7 +787,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW //This leave request is before the contract start date and will not be returned LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2015-12-30'), 'to_date' => CRM_Utils_Date::processDate('2015-12-30'), 'from_date_type' => 1, @@ -798,7 +798,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW // This will be returned $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -809,7 +809,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW // This will be returned $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -820,7 +820,7 @@ public function testGetCanReturnLeaveRequestsWithoutToDateWhichOverlapAContractW //This will not be returned as it is after the contract start date LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2017-12-30'), 'to_date' => CRM_Utils_Date::processDate('2017-12-30'), 'from_date_type' => 1, @@ -848,7 +848,7 @@ public function testGetFullIncludesTheBalanceChangeAndDatesForTheReturnedLeaveRe // This will be returned. The balance change will be -1 $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -859,7 +859,7 @@ public function testGetFullIncludesTheBalanceChangeAndDatesForTheReturnedLeaveRe // This will be returned. The balance change will be -4 $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -895,7 +895,7 @@ public function testGetFullShouldNotIncludeTheBalanceChangeIfTheReturnOptionIsNo $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -905,7 +905,7 @@ public function testGetFullShouldNotIncludeTheBalanceChangeIfTheReturnOptionIsNo $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -945,7 +945,7 @@ public function testGetFullShouldNotIncludeTheDatesIfTheReturnOptionIsNotEmptyAn $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -955,7 +955,7 @@ public function testGetFullShouldNotIncludeTheDatesIfTheReturnOptionIsNotEmptyAn $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -995,7 +995,7 @@ public function testGetFullIncludesBalanceChangesAndDatesForToilLeaveRequests() $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -1005,7 +1005,7 @@ public function testGetFullIncludesBalanceChangesAndDatesForToilLeaveRequests() $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -1014,7 +1014,7 @@ public function testGetFullIncludesBalanceChangesAndDatesForToilLeaveRequests() ], true); $toilRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date' => CRM_Utils_Date::processDate('2016-02-21'), @@ -1066,7 +1066,7 @@ public function testGetFullShouldNotIncludeTheBalanceChangeAndDatesIfTheReturnOp $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -1076,7 +1076,7 @@ public function testGetFullShouldNotIncludeTheBalanceChangeAndDatesIfTheReturnOp $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -1092,11 +1092,11 @@ public function testGetFullShouldNotIncludeTheBalanceChangeAndDatesIfTheReturnOp $expectedValues = [ [ 'id' => $leaveRequest1->id, - 'type_id' => 1 + 'type_id' => $this->absenceType->id ], [ 'id' => $leaveRequest2->id, - 'type_id' => 1 + 'type_id' => $this->absenceType->id ] ]; @@ -1118,7 +1118,7 @@ public function testGetDoesNotReturnALeaveRequestNotOverlappingAContractEvenIfIt //so it will not be returned LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2015-12-30'), 'to_date' => CRM_Utils_Date::processDate('2015-12-30'), 'from_date_type' => 1, @@ -1138,7 +1138,7 @@ public function testGetAndGetFullDoesNotReturnSoftDeletedLeaveRequests() { $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('+1 days'), 'to_date' => CRM_Utils_Date::processDate('+2 days'), 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE @@ -1146,7 +1146,7 @@ public function testGetAndGetFullDoesNotReturnSoftDeletedLeaveRequests() { $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('+3 days'), 'to_date' => CRM_Utils_Date::processDate('+4 days'), 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE @@ -1154,7 +1154,7 @@ public function testGetAndGetFullDoesNotReturnSoftDeletedLeaveRequests() { $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('+5 days'), 'to_date' => CRM_Utils_Date::processDate('+6 days'), 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE @@ -1426,7 +1426,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithoutActive $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1435,7 +1435,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithoutActive $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1444,7 +1444,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithoutActive $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember3['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-13'), 'to_date' => CRM_Utils_Date::processDate('2016-03-13'), 'from_date_type' => 1, @@ -1492,7 +1492,7 @@ public function testGetAndGetFullShouldReturnNoInformationForContactWithActiveLe LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1524,7 +1524,7 @@ public function testGetAndGetFullReturnsCorrectlyWhenTheContactIdIsPassedAsArray $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1533,7 +1533,7 @@ public function testGetAndGetFullReturnsCorrectlyWhenTheContactIdIsPassedAsArray $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-05-01'), 'to_date' => CRM_Utils_Date::processDate('2016-05-02'), 'from_date_type' => 1, @@ -1573,7 +1573,7 @@ public function testGetAndGetFullReturnsCorrectlyWhenTheContactIdIsPassedAsInteg $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1582,7 +1582,7 @@ public function testGetAndGetFullReturnsCorrectlyWhenTheContactIdIsPassedAsInteg $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-05-01'), 'to_date' => CRM_Utils_Date::processDate('2016-05-02'), 'from_date_type' => 1, @@ -1642,7 +1642,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithActiveLea $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1651,7 +1651,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithActiveLea $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1660,7 +1660,7 @@ public function testGetAndGetFullShouldReturnInformationForContactsWithActiveLea $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember3['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-13'), 'to_date' => CRM_Utils_Date::processDate('2016-03-13'), 'from_date_type' => 1, @@ -1709,7 +1709,7 @@ public function testGetAndGetFullShouldReturnEmptyResponseForALoggedInLeaveManag $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1718,7 +1718,7 @@ public function testGetAndGetFullShouldReturnEmptyResponseForALoggedInLeaveManag $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1767,7 +1767,7 @@ public function testGetAndGetFullShouldReturnResultsForContactsManagedByLoggedIn $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1776,7 +1776,7 @@ public function testGetAndGetFullShouldReturnResultsForContactsManagedByLoggedIn $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1818,7 +1818,7 @@ public function testGetAndGetFullShouldReturnEmptyResponseWhenManagedByParameter LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1872,7 +1872,7 @@ public function testGetAndGetFullOnlyReturnsResultsForContactsManagedActivelyByT $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -1881,7 +1881,7 @@ public function testGetAndGetFullOnlyReturnsResultsForContactsManagedActivelyByT $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -1890,7 +1890,7 @@ public function testGetAndGetFullOnlyReturnsResultsForContactsManagedActivelyByT $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember3['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-13'), 'to_date' => CRM_Utils_Date::processDate('2016-03-13'), 'from_date_type' => 1, @@ -1899,7 +1899,7 @@ public function testGetAndGetFullOnlyReturnsResultsForContactsManagedActivelyByT $leaveRequest4 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember4['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-15'), 'to_date' => CRM_Utils_Date::processDate('2016-03-17'), 'from_date_type' => 1, @@ -1954,7 +1954,7 @@ public function testCalculateBalanceChangeShouldNotAllowParamsWithoutContactID() 'from_date_type' => $this->leaveRequestDayTypes['half_day_am']['value'], 'to_date' => '2016-11-10', 'to_date_type' => $this->leaveRequestDayTypes['half_day_pm']['value'], - 'type_id' => 1 + 'type_id' => $this->absenceType->id ]); } @@ -1968,7 +1968,7 @@ public function testCalculateBalanceChangeShouldNotAllowParamsWithoutFromDate() 'from_date_type' => $this->leaveRequestDayTypes['half_day_am']['value'], 'to_date' => '2016-11-10', 'to_date_type' => $this->leaveRequestDayTypes['half_day_pm']['value'], - 'type_id' => 1 + 'type_id' => $this->absenceType->id ]); } @@ -2014,7 +2014,7 @@ public function testCalculateBalanceChangeShouldNotAllowParamsWithoutToDate() { 'from_date' => '2016-11-05', 'from_date_type' => $this->leaveRequestDayTypes['half_day_pm']['value'], 'to_date_type' => $this->leaveRequestDayTypes['half_day_pm']['value'], - 'type_id' => 1 + 'type_id' => $this->absenceType->id ]); } @@ -2061,7 +2061,7 @@ public function testCalculateBalanceChangeShouldNotAllowInvalidDate() { 'from_date_type' => $this->leaveRequestDayTypes['half_day_am']['value'], 'to_date' => '2016-11-10', 'to_date_type' => $this->leaveRequestDayTypes['half_day_pm']['value'], - 'type_id' => 1 + 'type_id' => $this->absenceType->id ]); } @@ -2149,7 +2149,8 @@ public function testCalculateBalanceChangeWithAllRequiredParameters() { 'from_date_type' => $fromType, 'to_date' => $toDate, 'to_date_type' => $toType, - 'type_id' => $absenceType->id + 'type_id' => $absenceType->id, + 'request_type' => LeaveRequest::REQUEST_TYPE_LEAVE ]); $this->assertEquals($expectedResultsBreakdown, $result['values']); } @@ -3208,7 +3209,7 @@ public function testDeleteAlsoDeletesLeaveRequestAndItsBalanceChangesFor() { $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => 1, - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => $startDate->format('Ymd'), 'from_date_type' => $this->leaveRequestDayTypes['all_day']['value'], 'to_date' => $endDate->format('Ymd'), @@ -3278,7 +3279,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -3287,7 +3288,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-01'), 'to_date' => CRM_Utils_Date::processDate('2016-02-01'), 'from_date_type' => 1, @@ -3296,7 +3297,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-05'), 'to_date' => CRM_Utils_Date::processDate('2016-01-05'), 'from_date_type' => 1, @@ -3305,7 +3306,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest4 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember3['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-13'), 'to_date' => CRM_Utils_Date::processDate('2016-03-13'), 'from_date_type' => 1, @@ -3314,7 +3315,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest5 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember4['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-10-23'), 'to_date' => CRM_Utils_Date::processDate('2016-10-23'), 'from_date_type' => 1, @@ -3365,7 +3366,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -3410,7 +3411,7 @@ public function testGetAndGetFullShouldOnlyReturnTheLeaveRequestsOfStaffMembersM $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -3463,7 +3464,7 @@ public function testIsManagedByShouldReturnTrueIfTheContactOfTheGivenLeaveReques $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -3493,7 +3494,7 @@ public function testIsManagedByShouldReturnFalseIfTheContactOfTheGivenLeaveReque $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $staffMember['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-01-01'), 'to_date' => CRM_Utils_Date::processDate('2016-01-01'), 'from_date_type' => 1, @@ -3614,7 +3615,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToLoggedInUserWhenUserIsNo LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -3624,7 +3625,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToLoggedInUserWhenUserIsNo LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -3669,7 +3670,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToContactsThatLoggedInUser LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -3679,7 +3680,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToContactsThatLoggedInUser LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -3738,7 +3739,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToContactsThatLoggedInUser $leaveRequestContact1 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -3748,7 +3749,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToContactsThatLoggedInUser LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -3758,7 +3759,7 @@ public function testGetAndGetFullReturnsOnlyDataLinkedToContactsThatLoggedInUser $leaveRequestContact3 = LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact3['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), 'from_date_type' => 1, @@ -3821,7 +3822,7 @@ public function testGetAndGetFullReturnsAllDataWhenLoggedInUserHasViewAllContact LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -3831,7 +3832,7 @@ public function testGetAndGetFullReturnsAllDataWhenLoggedInUserHasViewAllContact LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -3876,7 +3877,7 @@ public function testGetAndGetFullReturnsAllDataWhenLoggedInUserHasEditAllContact LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact1['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-02'), 'to_date' => CRM_Utils_Date::processDate('2016-03-02'), 'from_date_type' => 1, @@ -3886,7 +3887,7 @@ public function testGetAndGetFullReturnsAllDataWhenLoggedInUserHasEditAllContact LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contact2['id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), 'from_date_type' => 1, @@ -3918,14 +3919,14 @@ public function testGetAndGetFullIncludesAllTheRequestsUpToTheLastDayMinuteIfToD LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract1['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), //Hour will be automatically set to 00:00:00 'to_date' => CRM_Utils_Date::processDate('2016-02-23'), //Hour will be automatically set to 23:59:59 ], true); LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract2['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-23 10:00:00'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23 16:00:00'), ], true); @@ -3960,14 +3961,14 @@ public function testGetAndGetFullIncludesAllTheRequestsStartingFromTheFirstMinut LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract1['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20'), //Hour will be automatically set to 00:00:00 'to_date' => CRM_Utils_Date::processDate('2016-02-20'), //Hour will be automatically set to 23:59:59 ], true); LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract2['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-02-20 23:59:59'), 'to_date' => CRM_Utils_Date::processDate('2016-02-23 16:00:00'), ], true); @@ -3997,28 +3998,28 @@ public function testGetAndGetFullIncludesAllTheRequestsBetweenTheGivenPeriodAndF LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-17 08:00'), 'to_date' => CRM_Utils_Date::processDate('2016-03-17 09:00:00') ], true); LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-17 11:00'), 'to_date' => CRM_Utils_Date::processDate('2016-03-18 11:00:00') ], true); LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-25 17:00:00'), 'to_date' => CRM_Utils_Date::processDate('2016-03-25 18:00:00'), ], true); LeaveRequestFabricator::fabricateWithoutValidation([ 'contact_id' => $contract['contact_id'], - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'from_date' => CRM_Utils_Date::processDate('2016-03-25 19:00:00'), 'to_date' => CRM_Utils_Date::processDate('2016-03-25 20:00:00'), ], true); @@ -4142,7 +4143,7 @@ public function testGetBreakdownShouldReturnEmptyIfAStaffMemberTriesToGetTheBrea ); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => $contact2['id'], 'from_date' => CRM_Utils_Date::processDate('+5 days'), 'to_date' => CRM_Utils_Date::processDate('+7 days'), @@ -4179,7 +4180,7 @@ public function testGetBreakdownShouldReturnEmptyIfAManagerTriesToGetTheBreakdow ); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => $contact2['id'], 'from_date' => CRM_Utils_Date::processDate('+5 days'), 'to_date' => CRM_Utils_Date::processDate('+7 days'), @@ -4209,7 +4210,7 @@ public function testGetBreakdownShouldNotReturnEmptyIfAManagerTriesToGetTheBreak ); $leaveRequest = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => $contact2['id'], 'from_date' => CRM_Utils_Date::processDate('+5 days'), 'to_date' => CRM_Utils_Date::processDate('+7 days'), @@ -4242,14 +4243,14 @@ public function testGetBreakdownReturnsResultsIfAnAdminTriesToAccessTheBreakdown ); $leaveRequest1 = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => $contact1['id'], 'from_date' => CRM_Utils_Date::processDate('+5 days'), 'to_date' => CRM_Utils_Date::processDate('+7 days'), ], true); $leaveRequest2 = LeaveRequestFabricator::fabricateWithoutValidation([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => $contact2['id'], 'from_date' => CRM_Utils_Date::processDate('+8 days'), 'to_date' => CRM_Utils_Date::processDate('+8 days'), @@ -4285,7 +4286,7 @@ private function getExpectedArrayForIsValidError($field, $code) { private function mergeWithDefaultLeaveRequestParams($params) { return array_merge([ - 'type_id' => 1, + 'type_id' => $this->absenceType->id, 'contact_id' => 1, 'status_id' => 1, 'from_date_type' => 1, @@ -4373,6 +4374,55 @@ public function testTheTimeForFromAndToDateOfLeaveRequestIsAddedCorrectlyWhenLea $this->assertEquals($toDate->format('Y-m-d') ." 23:59:00", $leaveRequest->to_date); } + public function testTheTimeForFromAndToDateOfLeaveRequestStaysUntouchedWhenRequestIsTOIL() { + $absenceType = AbsenceTypeFabricator::fabricate([ + 'allow_accruals_request' => true, + 'max_leave_accrual' => 10, + 'allow_accrue_in_the_past' => true + ]); + $fromDate = new DateTime('2016-01-08 01:23:45'); + $toDate = new DateTime('2016-01-10 12:34:56'); + $contactID = 1; + $this->registerCurrentLoggedInContactInSession($contactID); + + $period = AbsencePeriodFabricator::fabricate([ + 'start_date' => $fromDate->format('YmdHis'), + 'end_date' => $toDate->format('YmdHis'), + ]); + + $contract = HRJobContractFabricator::fabricate( + ['contact_id' => $contactID], + ['period_start_date' => $fromDate->format('Y-m-d')] + ); + + $periodEntitlement = LeavePeriodEntitlementFabricator::fabricate([ + 'type_id' => $absenceType->id, + 'contact_id' => $contactID, + 'period_id' => $period->id + ]); + + $entitlementBalanceChange = 3; + $this->createLeaveBalanceChange($periodEntitlement->id, $entitlementBalanceChange); + WorkPatternFabricator::fabricateWithA40HourWorkWeek(['is_default' => true]); + + $result = civicrm_api3('LeaveRequest', 'create', [ + 'contact_id' => $contract['contact_id'], + 'type_id' => $absenceType->id, + 'from_date' => $fromDate->format('Y-m-d H:i:s'), + 'from_date_type' => $this->leaveRequestDayTypes['all_day']['value'], + 'to_date' => $toDate->format('Y-m-d H:i:s'), + 'to_date_type' => $this->leaveRequestDayTypes['all_day']['value'], + 'status_id' => 3, + 'toil_duration' => 10, + 'toil_to_accrue' => 2, + 'request_type' => LeaveRequest::REQUEST_TYPE_TOIL, + ]); + + $leaveRequest = LeaveRequest::findById($result['id']); + $this->assertEquals($fromDate->format('Y-m-d H:i:s'), $leaveRequest->from_date); + $this->assertEquals($toDate->format('Y-m-d H:i:s'), $leaveRequest->to_date); + } + public function testCreateReturnsFalseForFromEmailParameterWhenFromEmailIsNotConfigured() { $contactID = 1; $this->registerCurrentLoggedInContactInSession($contactID); @@ -4627,4 +4677,3 @@ public function testGetContactWorkDayForDateThrowsAnExceptionWhenThereIsNoWorkDa ); } } - diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-container.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-container.html index ebb325809dc..49f2d79ae32 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-container.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-container.html @@ -1,7 +1,6 @@
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-custom-work-pattern-modal.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-custom-work-pattern-modal.html index 320516ee55f..ce5aab6263a 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-custom-work-pattern-modal.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-custom-work-pattern-modal.html @@ -46,15 +46,24 @@
    -
    - - +
    +
    +
    + + +
    +
    +
    + + + +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-work-patterns.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-work-patterns.html index 1841e0ae6b5..07c8fafdddf 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-work-patterns.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/absence-tab/components/absence-tab-work-patterns.html @@ -1,8 +1,6 @@ -
    - -
    + diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/admin-dashboard/components/admin-dashboard-container.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/admin-dashboard/components/admin-dashboard-container.html index 9170855c942..17366f6455e 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/admin-dashboard/components/admin-dashboard-container.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/admin-dashboard/components/admin-dashboard-container.html @@ -2,7 +2,6 @@
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/manager-leave/components/manager-leave-container.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/manager-leave/components/manager-leave-container.html index f3cafdd9c82..ae09d81edfa 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/manager-leave/components/manager-leave-container.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/manager-leave/components/manager-leave-container.html @@ -1,5 +1,8 @@
    + + - -
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-day.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-day.html index 636a3730eed..d6cdb346f4d 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-day.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-day.html @@ -1,79 +1,89 @@ -
    - - - {{day.label}} +
    + + + {{day.contactData.leaveRequestsAttributes[leaveRequest.id].label}} + - - - -
    - - - - - + +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-legend.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-legend.html index c88fda50f76..d60e2f00c3e 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-legend.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-legend.html @@ -94,19 +94,19 @@

    -
    +
    Weekend
    -
    +
    Public Holiday
    -
    +
    Non Working Day
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-month.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-month.html index 5f4592c2d42..486540a1354 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-month.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-calendar-month.html @@ -14,7 +14,7 @@

    {{month.month.name}} {{month.month.year}}

    - - @@ -50,7 +50,7 @@

    {{month.month.name}} {{month.month.year}}

    - - + - +
    +
    + {{contact.display_name}} {{contact.display_name}}
    +
    @@ -19,7 +19,7 @@ ng-change="detailsTab.dateChangeHandler('from')"/>
    -
    +
    @@ -29,7 +29,7 @@
    - -
    -
    -
    - {{detailsTab.uiOptions.times.to.amount | timeUnitApplier : detailsTab.selectedAbsenceType.calculation_unit_name}} - for {{detailsTab.uiOptions.toDate | formatDate}} or - - set custom deduction -
    +
    + +
    +
    +
    + {{detailsTab.uiOptions.times.to.amount | timeUnitApplier : detailsTab.selectedAbsenceType.calculation_unit_name}} + for {{detailsTab.uiOptions.toDate | formatDate}} or + + set custom deduction
    -
    -
    - Customise deduction for - {{detailsTab.uiOptions.toDate | formatDate}} - - (eg. subtract break time) -
    -
    - - - - -
    +
    +
    +
    + Customise deduction for + {{detailsTab.uiOptions.toDate | formatDate}} + + (eg. subtract break time) +
    +
    + + + +
    - -
    +
    +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/by-unit-and-days-mode/hours-unit-single-day.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/by-unit-and-days-mode/hours-unit-single-day.html index c89cbcb6894..0b12127b745 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/by-unit-and-days-mode/hours-unit-single-day.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/by-unit-and-days-mode/hours-unit-single-day.html @@ -27,7 +27,7 @@
    -
    +
    - - +
    + +
    +
    + +
    @@ -24,6 +32,6 @@
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/sickness.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/sickness.html index 286fda35960..7da9dd80eaf 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/sickness.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-popup/details-tab/sickness.html @@ -3,7 +3,7 @@
    -
    +
    - - - - - - - - - - - - - - - -
    +
    +
    +
    + {{detailsTab.uiOptions.toil_duration_in_hours | timeUnitApplier : 'hours'}} + of overtime worked + + Customise this amount +
    +
    +
    +
    +
    -
    -
    - - +
    + + + +
    +
    @@ -56,29 +39,37 @@
    -
    -
    - - +
    +
    +
    + + +
    +
    + + + +
    +
    +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-record-actions.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-record-actions.html index d17bf608bd7..81d404e95cb 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-record-actions.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/leave-request-record-actions.html @@ -1,14 +1,30 @@ -
    - - +
    +
    + + +
    +
    + +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/manage-leave-requests.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/manage-leave-requests.html index 58785da6898..e697cd1ed5f 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/manage-leave-requests.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/manage-leave-requests.html @@ -184,17 +184,8 @@

    Manager Absence Approval 0 ? "+" : ""}}{{request.balance_change | timeUnitApplier : absenceType.calculation_unit_name}}

    - {{request.from_date | formatDate : null : request.request_type !== 'toil' ? unit : null}} - - - - {{request.to_date | formatDate : null : request.request_type !== 'toil' ? unit : null}} - - - - - {{request.to_date.slice(11, 16)}} - - {{vm.getLeaveStatusByValue(request.status_id)}} + - + {{request.to_date | formatDate : null : (request.request_type === 'toil' ? 'hours' : unit)}} + + + - + {{request.to_date.slice(11, 16)}} + diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/partials/staff-leave-report-requests-rows.html b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/partials/staff-leave-report-requests-rows.html index d45ffc17a79..7b6165c360e 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/partials/staff-leave-report-requests-rows.html +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/views/shared/components/partials/staff-leave-report-requests-rows.html @@ -7,17 +7,8 @@ (expires {{request.toil_expiry_date | formatDate}}) - {{request.from_date | formatDate : null : request.request_type !== 'toil' ? unit : null}} - - - - {{request.to_date | formatDate : null : request.request_type !== 'toil' ? unit : null}} - - - - - {{request.to_date.slice(11, 16)}} - - {{report.leaveRequestStatuses[request.status_id].label}} diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/option_groups/work_pattern_change_reason_install.xml b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/option_groups/work_pattern_change_reason_install.xml new file mode 100644 index 00000000000..611be1a0d4b --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/option_groups/work_pattern_change_reason_install.xml @@ -0,0 +1,52 @@ + + + + + + + hrleaveandabsences_work_pattern_change_reason + Work Pattern Change Reason + 1 + 1 + + + + + + + 1 + as_per_contract + 1 + 1 + 0 + 0 + 1 + hrleaveandabsences_work_pattern_change_reason + + + + + 2 + change_in_contractual_hours + 0 + 2 + 0 + 0 + 1 + hrleaveandabsences_work_pattern_change_reason + + + + + 3 + change_in_contract_type + 0 + 3 + 0 + 0 + 1 + hrleaveandabsences_work_pattern_change_reason + + + + diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/ContactWorkPattern.xml b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/ContactWorkPattern.xml index 1e0f18cd1be..cf51391c881 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/ContactWorkPattern.xml +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/ContactWorkPattern.xml @@ -73,7 +73,7 @@ One of the values of the Job Contract Revision Change Reason option group 4.4 - hrjc_revision_change_reason + hrleaveandabsences_work_pattern_change_reason diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.entityType.php b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.entityType.php new file mode 100644 index 00000000000..9c5dd3d6f28 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.entityType.php @@ -0,0 +1,11 @@ + + array ( + 'name' => 'LeaveBalanceChangeExpiryLog', + 'class' => 'CRM_HRLeaveAndAbsences_DAO_LeaveBalanceChangeExpiryLog', + 'table' => 'civicrm_leave_balance_change_expiry_log', + ), +); diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.xml b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.xml new file mode 100644 index 00000000000..34497085b92 --- /dev/null +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/LeaveBalanceChangeExpiryLog.xml @@ -0,0 +1,96 @@ + + + + CRM/HRLeaveAndAbsences + LeaveBalanceChangeExpiryLog + civicrm_hrleaveandabsences_leave_balance_change_expiry_log + Leave Balance Change Expiry Log + 4.4 + true + + + id + int unsigned + true + Unique LeaveBalanceChangeExpiryLog ID + 4.4 + + + id + true + + + + balance_change_id + int unsigned + true + The expired balance change ID + 4.4 + + + + amount + decimal + true + 0 + The expired balance amount + 4.4 + + + + source_id + int unsigned + true + Expired Balance change source ID + 4.4 + + + + source_type + varchar + true + 20 + Expired Balance change source type + 4.4 + + + + expiry_date + date + true + The balance change expiry date + 4.4 + + + + balance_type_id + int unsigned + true + One of the values of the Leave Balance Type option group + 4.4 + + hrleaveandabsences_leave_balance_change_type + + + + + leave_date + date + The Leave date of the expired balance change (i.e If it is a leave request balance change) + 4.4 + + + + leave_request_id + int unsigned + The Leave Request ID linked to the expired balance change (i.e If it is a leave request balance change) + 4.4 + + + + created_date + datetime + The date and time this log was created + 4.4 + +
    diff --git a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/files.xml b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/files.xml index d4ce96f8978..e2e03c2040f 100644 --- a/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/files.xml +++ b/uk.co.compucorp.civicrm.hrleaveandabsences/xml/schema/CRM/HRLeaveAndAbsences/files.xml @@ -14,4 +14,5 @@ + diff --git a/uk.co.compucorp.civicrm.hrsampledata/info.xml b/uk.co.compucorp.civicrm.hrsampledata/info.xml index bffdb204eab..4a40caf84dd 100644 --- a/uk.co.compucorp.civicrm.hrsampledata/info.xml +++ b/uk.co.compucorp.civicrm.hrsampledata/info.xml @@ -8,8 +8,8 @@ Compucorp info@compucorp.com - 2018-03-26 - 1.7.5 + 2018-04-30 + 1.7.6 stable 4.7