Skip to content

Commit

Permalink
Improved SLA Policy elements
Browse files Browse the repository at this point in the history
  • Loading branch information
rskrzypczak committed Aug 26, 2022
1 parent 344a6e1 commit e558867
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 235 deletions.
2 changes: 1 addition & 1 deletion config/version.php
@@ -1,7 +1,7 @@
<?php

return [
'appVersion' => '6.4.15',
'appVersion' => '6.4.16',
'patchVersion' => '2022.08.26',
'lib_roundcube' => '0.3.1',
];
8 changes: 0 additions & 8 deletions languages/en-US/ServiceContracts.json
Expand Up @@ -48,13 +48,5 @@
"LBL_STATUS": "Status",
"LBL_CONDITIONS": "Conditions",
"LBL_TIMES": "Times"
},
"js": {
"JS_POLICY_NAME": "Policy name",
"JS_OPERATIONAL_HOURS": "Operational hours",
"JS_REACTION_TIME": "Reaction time",
"JS_IDLE_TIME": "Idle time",
"JS_RESOLVE_TIME": "Resolve time",
"JS_BUSINESS_HOURS": "Business hours"
}
}
95 changes: 44 additions & 51 deletions layouts/basic/modules/ServiceContracts/CustomConditions.tpl
@@ -1,67 +1,60 @@
{*<!-- {[The file is published on the basis of YetiForce Public License 5.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} -->*}
{strip}
<!-- tpl-ServiceContracts-CustomConditions -->
<input type="hidden" class="js-all-business-hours" value="{\App\Purifier::encodeHtml(\App\Json::encode($ALL_BUSINESS_HOURS))}">
<div class="d-none js-conditions-template" data-js="container">
{include file=\App\Layout::getTemplatePath('ConditionBuilder.tpl', $MODULE_NAME) ADVANCE_CRITERIA=[]}
</div>
<div class="js-custom-conditions" data-js="container">
{foreach item=ROW from=$SLA_POLICY_ROWS key=$ROW_INDEX}
{if $ROW['policy_type']===2}
<div class="card js-custom-row shadow-sm mb-2" data-id="{$ROW['id']}" data-record-id="{$RECORD->getId()}" data-js="container">
<div class="card-body">
<div class="d-flex">
<div class="d-block" style="flex-grow:1">
<div class="row no-gutters">
<div class="col-5 pr-2">
{assign var=ROW_HOURS value=explode(',', $ROW['business_hours'])}
<label>{\App\Language::translate('LBL_BUSINESS_HOURS', 'ServiceContracts')}</label>
<div>
<select class="select2 js-business-hours" name="business_hours[{$ROW_INDEX}][]" multiple data-validation-engine="validate[required,funcCall[Vtiger_Base_Validator_Js.invokeValidation]]">
{foreach item=BUSINESS_HOURS from=$ALL_BUSINESS_HOURS}
<option value="{$BUSINESS_HOURS['id']}" {if in_array($BUSINESS_HOURS['id'], $ROW_HOURS)}selected="selected" {/if}>{$BUSINESS_HOURS['name']}</option>
{/foreach}
</select>
</div>
{foreach item=ROW from=$SLA_POLICY_ROWS key=$ROW_INDEX}
{if $ROW['policy_type']===2}
<div class="card js-custom-row shadow-sm mb-2" data-id="{$ROW['id']}" data-record-id="{$RECORD->getId()}" data-js="container">
<div class="card-body">
<div class="d-flex">
<div class="d-block" style="flex-grow:1">
<div class="row no-gutters">
<div class="col-5 pr-2">
{assign var=ROW_HOURS value=explode(',', $ROW['business_hours'])}
<label>{\App\Language::translate('LBL_BUSINESS_HOURS', 'ServiceContracts')}</label>
<div>
<select class="select2 js-business-hours" name="business_hours[{$ROW_INDEX}][]" multiple data-validation-engine="validate[required,funcCall[Vtiger_Base_Validator_Js.invokeValidation]]">
{foreach item=BUSINESS_HOURS from=$ALL_BUSINESS_HOURS}
<option value="{$BUSINESS_HOURS['id']}" {if in_array($BUSINESS_HOURS['id'], $ROW_HOURS)}selected="selected" {/if}>{$BUSINESS_HOURS['name']}</option>
{/foreach}
</select>
</div>
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_REACTION_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="reaction_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['reaction_time']}">
</div>
</div>
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_IDLE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="idle_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['idle_time']}">
</div>
</div>
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_REACTION_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="reaction_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['reaction_time']|escape}">
</div>
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_RESOLVE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="resolve_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['resolve_time']}">
</div>
</div>
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_IDLE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="idle_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['idle_time']|escape}">
</div>
</div>
<div class="row mt-2">
<div class="js-conditions-col col">
<label>{\App\Language::translate('LBL_CONDITIONS', $MODULE_NAME)}</label>
<input type="hidden" name="rowid[{$ROW_INDEX}]" value="{$ROW['id']}" class="js-custom-row-id" />
<input type="hidden" name="conditions[{$ROW_INDEX}]" class="js-conditions-value" value="{\App\Purifier::encodeHtml($ROW['conditions'])}" data-js="container">
{include file=\App\Layout::getTemplatePath('ConditionBuilder.tpl', $MODULE_NAME) ADVANCE_CRITERIA=\App\Json::decode($ROW['conditions'])}
<div class="col-2 pr-2">
<label>{\App\Language::translate('LBL_RESOLVE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="resolve_time[{$ROW_INDEX}]" class="c-time-period" value="{$ROW['resolve_time']|escape}">
</div>
</div>
</div>
<div class="d-inline-flex text-right border-left" style="flex-grow:0">
<div class="d-inline-block align-center" style="margin:auto 0;">
<a href class="btn btn-danger ml-4 js-delete-row-action"><span class="fas fa-trash-alt"></span></a>
<div class="row mt-2">
<div class="js-conditions-col col">
<label>{\App\Language::translate('LBL_CONDITIONS', $MODULE_NAME)}</label>
<input type="hidden" name="rowid[{$ROW_INDEX}]" value="{$ROW['id']}" class="js-custom-row-id" />
<input type="hidden" name="conditions[{$ROW_INDEX}]" class="js-conditions-value" value="{\App\Purifier::encodeHtml($ROW['conditions'])}" data-js="container">
{include file=\App\Layout::getTemplatePath('ConditionBuilder.tpl', $MODULE_NAME) ADVANCE_CRITERIA=\App\Json::decode($ROW['conditions'])}
</div>
</div>
</div>
<div class="d-inline-flex text-right border-left" style="flex-grow:0">
<div class="d-inline-block align-center" style="margin:auto 0;">
<a href class="btn btn-danger ml-4 js-delete-row-action"><span class="fas fa-trash-alt"></span></a>
</div>
</div>
</div>
</div>
{/if}
{/foreach}
</div>
</div>
{/if}
{/foreach}
<!-- /tpl-ServiceContracts-CustomConditions -->
{/strip}
4 changes: 3 additions & 1 deletion layouts/basic/modules/ServiceContracts/SlaPolicy.tpl
Expand Up @@ -25,7 +25,9 @@
<div class="js-sla-policy-template js-sla-policy-template--container form-group row d-none" data-js="container"></div>
<div class="js-sla-policy-custom form-group row d-none" data-js="container">
<div class="col-12">
{include file=\App\Layout::getTemplatePath('CustomConditions.tpl', $MODULE_NAME)}
<div class="js-custom-conditions" data-js="container">
{include file=\App\Layout::getTemplatePath('CustomConditions.tpl', $MODULE_NAME)}
</div>
</div>
</div>
<div class="row">
Expand Down
41 changes: 41 additions & 0 deletions layouts/basic/modules/ServiceContracts/SlaPolicyCustom.tpl
@@ -0,0 +1,41 @@
{*<!-- {[The file is published on the basis of YetiForce Public License 5.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} -->*}
{strip}
<!-- tpl-ServiceContracts-SlaPolicyCustom -->
<div class="js-sla-policy relatedContainer" data-js="container">
<input type="hidden" name="target" value="{$TARGET_MODULE}">
<div class="form-group row text-center">
<div class="col-12 flex">
<label class="d-inline-block mr-2">
{\App\Language::translate('LBL_POLICY_TYPE', $MODULE_NAME)}:
</label>
<label class="d-inline-block mr-2">
<input type="radio" name="policy_type" class="form-control d-inline-block mr-1 js-sla-policy-type-radio" value="0" {if $POLICY_TYPE===0} checked="checked" {/if} />{\App\Language::translate('LBL_POLICY_TYPE_GLOBAL', $MODULE_NAME)}
</label>
<label class="d-inline-block mr-2">
<input type="radio" name="policy_type" class="form-control d-inline-block mr-1 js-sla-policy-type-radio" value="1" {if $POLICY_TYPE===1} checked="checked" {/if} />{\App\Language::translate('LBL_POLICY_TYPE_TEMPLATE', $MODULE_NAME)}
</label>
<label class="d-inline-block mr-2">
<input type="radio" name="policy_type" class="form-control d-inline-block mr-1 js-sla-policy-type-radio" value="2" {if $POLICY_TYPE===2} checked="checked" {/if} /> {\App\Language::translate('LBL_POLICY_TYPE_CUSTOM', $MODULE_NAME)}
</label>
<button class="js-sla-policy-custom js-sla-policy-add-record-btn btn btn-success float-right d-none" data-record-id="{$RECORD->getId()}">
<span class="fas fa-plus"></span> {\App\Language::translate('LBL_ADD_ENTRY', $MODULE_NAME)}
</button>
</div>
</div>
<div class="js-sla-policy-template js-sla-policy-template--container form-group row d-none" data-js="container"></div>
<div class="js-sla-policy-custom form-group row d-none" data-js="container">
<div class="col-12">
{include file=\App\Layout::getTemplatePath('CustomConditions.tpl', $MODULE_NAME)}
</div>
</div>
<div class="row">
<div class="col text-center">
<button class="btn btn-success js-sla-policy-save-btn">
<span class="fas fa-check mr-2"></span>
{\App\Language::translate('LBL_SAVE')}
</button>
</div>
</div>
</div>
<!-- /tpl-ServiceContracts-SlaPolicyCustom -->
{/strip}
31 changes: 31 additions & 0 deletions layouts/basic/modules/ServiceContracts/SlaPolicyTemplate.tpl
@@ -0,0 +1,31 @@
{*<!-- {[The file is published on the basis of YetiForce Public License 5.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} -->*}
{strip}
<!-- tpl-ServiceContracts-SlaPolicyTemplate -->
<div class="col-12">
<table class="table js-sla-policy-template-table">
<thead>
<tr>
<th></th>
<th>{\App\Language::translate('LBL_POLICY_NAME', $MODULE_NAME)}</th>
<th>{\App\Language::translate('LBL_OPERATIONAL_HOURS', $MODULE_NAME)}</th>
<th>{\App\Language::translate('LBL_REACTION_TIME', $MODULE_NAME)}</th>
<th>{\App\Language::translate('LBL_IDLE_TIME', $MODULE_NAME)}</th>
<th>{\App\Language::translate('LBL_RESOLVE_TIME', $MODULE_NAME)}</th>
</tr>
</thead>
<tbody>
{foreach from=\App\Utils\ServiceContracts::getSlaPolicyByModule($TARGET_MODULE_ID) item=ROW key=key name=slaTemplates}
<tr>
<td><input type="radio" name="policy_id" value="{$ROW['id']}" {if $SELECTED_TEMPLATE === $ROW['id'] || (!$SELECTED_TEMPLATE && $smarty.foreach.slaTemplates.first)} checked="checked" {/if}></td>
<td>{\App\Purifier::encodeHtml($ROW.name)}</td>
<td>{\App\Purifier::encodeHtml($ROW.operational_hours)}</td>
<td>{\App\Purifier::encodeHtml($ROW.reaction_time)}</td>
<td>{\App\Purifier::encodeHtml($ROW.idle_time)}</td>
<td>{\App\Purifier::encodeHtml($ROW.resolve_time)}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
<!-- /tpl-ServiceContracts-SlaPolicyTemplate -->
{/strip}
12 changes: 6 additions & 6 deletions layouts/basic/modules/Settings/SlaPolicy/EditViewBlocks.tpl
Expand Up @@ -21,7 +21,7 @@
<div class="card-header">
{if !empty($RECORD->getId())}
<span class="yfi yfi-full-editing-view mr-2"></span>
{\App\Language::translate('LBL_EDIT',$QUALIFIED_MODULE)} - {$RECORD->getName()}
{\App\Language::translate('LBL_EDIT',$QUALIFIED_MODULE)} - {\App\Purifier::encodeHtml($RECORD->getName())}
{else}
<span class="fas fa-plus mr-2"></span>
{\App\Language::translate('LBL_CREATE',$QUALIFIED_MODULE)}
Expand All @@ -31,13 +31,13 @@
<div class="form-group row">
<div class="col-12 col-md-3">
<label>{\App\Language::translate('LBL_NAME',$QUALIFIED_MODULE)}</label>
<input type="text" name="name" class="form-control" value="{$RECORD->getName()}" data-validation-engine="validate[required,maxSize[255]]">
<input type="text" name="name" class="form-control" value="{\App\Purifier::encodeHtml($RECORD->getName())}" data-validation-engine="validate[required,maxSize[255]]">
</div>
<div class="col-12 col-md-3">
<label>{\App\Language::translate('LBL_SOURCE_MODULE',$QUALIFIED_MODULE)}</label>
<select name="source_module" class="select2" data-validation-engine="validate[required]">
{foreach item=MODULE_NAME from=$MODULES}
<option value="{$MODULE_NAME}" {if \App\Module::getModuleName($RECORD->get('tabid')) === $MODULE_NAME}selected="selected" {/if}>{\App\Language::translate($MODULE_NAME, $MODULE_NAME)}</option>
<option value="{$MODULE_NAME|escape}" {if \App\Module::getModuleName($RECORD->get('tabid')) === $MODULE_NAME}selected="selected" {/if}>{\App\Language::translate($MODULE_NAME, $MODULE_NAME)}</option>
{/foreach}
</select>
</div>
Expand Down Expand Up @@ -66,19 +66,19 @@
<div class="col-12 col-md-4">
<label>{\App\Language::translate('LBL_REACTION_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="reaction_time" class="c-time-period" value="{$RECORD->get('reaction_time')}">
<input type="hidden" name="reaction_time" class="c-time-period" value="{$RECORD->get('reaction_time')|escape}">
</div>
</div>
<div class="col-12 col-md-4">
<label>{\App\Language::translate('LBL_IDLE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="idle_time" class="c-time-period" value="{$RECORD->get('idle_time')}">
<input type="hidden" name="idle_time" class="c-time-period" value="{$RECORD->get('idle_time')|escape}">
</div>
</div>
<div class="col-12 col-md-4">
<label>{\App\Language::translate('LBL_RESOLVE_TIME','ServiceContracts')}</label>
<div class="input-group time">
<input type="hidden" name="resolve_time" class="c-time-period" value="{$RECORD->get('resolve_time')}">
<input type="hidden" name="resolve_time" class="c-time-period" value="{$RECORD->get('resolve_time')|escape}">
</div>
</div>
</div>
Expand Down
48 changes: 0 additions & 48 deletions modules/ServiceContracts/actions/PolicyTemplatesAjax.php

This file was deleted.

73 changes: 73 additions & 0 deletions modules/ServiceContracts/views/PolicyTemplatesAjax.php
@@ -0,0 +1,73 @@
<?php
/**
* ServiceContracts PolicyTemplatesAjax View class.
*
* @package View
*
* @copyright YetiForce S.A.
* @license YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
* @author Radosław Skrzypczak <r.skrzypczak@yetiforce.com>
*/
class ServiceContracts_PolicyTemplatesAjax_View extends Vtiger_Index_View
{
use \App\Controller\ExposeMethod;

/** @var Vtiger_Record_Model Record model instance. */
public $record;

/**
* Construct.
*/
public function __construct()
{
parent::__construct();
$this->exposeMethod('slaPolicyTemplate');
$this->exposeMethod('slaPolicyCustom');
}

/** {@inheritdoc} */
public function checkPermission(App\Request $request)
{
$this->record = Vtiger_Record_Model::getInstanceById($request->getInteger('record'), $request->getModule());
if (!$this->record->isViewable() || !$this->record->isPermitted('ServiceContractsSla') || !App\Privilege::isPermitted($request->getByType('targetModule', \App\Purifier::ALNUM))) {
throw new \App\Exceptions\NoPermittedToRecord('ERR_NO_PERMISSIONS_FOR_THE_RECORD', 406);
}
}

/** {@inheritdoc} */
public function slaPolicyTemplate(App\Request $request)
{
$moduleName = $request->getModule();
$sla = \App\Utils\ServiceContracts::getSlaPolicyForServiceContracts($request->getInteger('record'));
$slaId = $sla[0]['sla_policy_id'] ?? 0;

$viewer = $this->getViewer($request);
$viewer->assign('TARGET_MODULE_ID', \App\Module::getModuleId($request->getByType('targetModule', \App\Purifier::ALNUM)));
$viewer->assign('SELECTED_TEMPLATE', $slaId);

return $viewer->view('SlaPolicyTemplate.tpl', $moduleName);
}

/** {@inheritdoc} */
public function slaPolicyCustom(App\Request $request)
{
$moduleName = $request->getModule();
$index = $request->getInteger('index', time());
$defaultEmptyData = [
'id' => 0,
'policy_type' => 2,
'conditions' => '[]',
'reaction_time' => '1:d',
'idle_time' => '1:d',
'resolve_time' => '1:d',
'business_hours' => '',
];

$viewer = $this->getViewer($request);
$viewer->assign('RECORD', $this->record);
$viewer->assign('ALL_BUSINESS_HOURS', \App\Utils\ServiceContracts::getAllBusinessHours());
$viewer->assign('SLA_POLICY_ROWS', [$index => $defaultEmptyData]);

return $viewer->view('CustomConditions.tpl', $moduleName);
}
}

0 comments on commit e558867

Please sign in to comment.