CVE-2022-3005 (Other, published 2022-09-20T11:15Z)
Description: value: Cross-site Scripting (XSS) - Stored in GitHub repository yetiforcecompany/yetiforcecrm prior to 6.4.0.
Severity: nan (CVSS v3 base score: 5.4)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/yetiforcecompany/yetiforcecrm
Files changed:
config/version.php
languages/en-US/ServiceContracts.json
layouts/basic/modules/ServiceContracts/CustomConditions.tpl
layouts/basic/modules/ServiceContracts/SlaPolicy.tpl
layouts/basic/modules/ServiceContracts/SlaPolicyCustom.tpl
layouts/basic/modules/ServiceContracts/SlaPolicyTemplate.tpl
layouts/basic/modules/Settings/SlaPolicy/EditViewBlocks.tpl
modules/ServiceContracts/views/PolicyTemplatesAjax.php
public_html/layouts/basic/modules/ServiceContracts/resources/Detail.js
Commit message: Improved SLA Policy elements


Vulnerable code:
	'appVersion' => '6.4.15',
  },
  "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"
	<!-- 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>
									<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 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 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="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>
			{/if}
		{/foreach}
	</div>
				{include file=\App\Layout::getTemplatePath('CustomConditions.tpl', $MODULE_NAME)}
							{\App\Language::translate('LBL_EDIT',$QUALIFIED_MODULE)} - {$RECORD->getName()}
								<input type="text" name="name" class="form-control" value="{$RECORD->getName()}" data-validation-engine="validate[required,maxSize[255]]">
										<option value="{$MODULE_NAME}" {if \App\Module::getModuleName($RECORD->get('tabid')) === $MODULE_NAME}selected="selected" {/if}>{\App\Language::translate($MODULE_NAME, $MODULE_NAME)}</option>
									<input type="hidden" name="reaction_time" class="c-time-period" value="{$RECORD->get('reaction_time')}">
									<input type="hidden" name="idle_time" class="c-time-period" value="{$RECORD->get('idle_time')}">
									<input type="hidden" name="resolve_time" class="c-time-period" value="{$RECORD->get('resolve_time')}">
<?php
/**
 * ServiceContracts PolicyTemplatesAjax Action class.
 *
 * @package   Action
 *
 * @copyright YetiForce S.A.
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Rafal Pospiech <r.pospiech@yetiforce.com>
 * @author    Mariusz Krzaczkowski <m.krzaczkowski@yetiforce.com>
 */
class ServiceContracts_PolicyTemplatesAjax_Action extends \App\Controller\Action
{
	/** {@inheritdoc} */
	public function checkPermission(App\Request $request)
	{
		$record = Vtiger_DetailView_Model::getInstance($request->getModule(), $request->getInteger('record'));
		if (!$record->getRecord()->isViewable()) {
			throw new \App\Exceptions\NoPermittedToRecord('ERR_NO_PERMISSIONS_FOR_THE_RECORD', 406);
		}
	}

	/** {@inheritdoc} */
	public function process(App\Request $request)
	{
		$sla = \App\Utils\ServiceContracts::getSlaPolicyForServiceContracts($request->getInteger('record'));
		$slaId = $sla ? $sla[0]['sla_policy_id'] : false;
		$rows = [];
		foreach (\App\Utils\ServiceContracts::getSlaPolicyByModule(\App\Module::getModuleId($request->getByType('targetModule', 'Alnum'))) as $row) {
			$moduleName = \App\Module::getModuleName($row['tabid']);
			$row['tabid'] = \App\Language::translate($moduleName, $moduleName);
			$row['operational_hours'] = $row['operational_hours'] ? \App\Language::translate('LBL_CALENDAR_HOURS', 'ServiceContracts') : \App\Language::translate('LBL_BUSINESS_HOURS', 'ServiceContracts');
			$row['business_hours'] = implode(', ', array_column(\App\Utils\ServiceContracts::getBusinessHoursByIds(explode(',', $row['business_hours'])), 'name'));
			$row['reaction_time'] = \App\Fields\TimePeriod::getLabel($row['reaction_time']);
			$row['idle_time'] = \App\Fields\TimePeriod::getLabel($row['idle_time']);
			$row['resolve_time'] = \App\Fields\TimePeriod::getLabel($row['resolve_time']);
			if ($row['id'] === $slaId) {
				$row['checked'] = true;
			} else {
				$row['checked'] = false;
			}
			$rows[] = $row;
		}
		$response = new Vtiger_Response();
		$response->setResult($rows);
		$response->emit();
	}
}

		 * Get template table
		 * @param {Array} rows
		 *
		 * @returns {String} HTML
		getTemplateTableHtml(rows) {
			let somethingChecked = false;
			rows.forEach((row) => {
				if (row.checked) {
					somethingChecked = true;
					return false;
				}
			});
			if (!somethingChecked && typeof rows[0] !== 'undefined') {
				rows[0].checked = true;
			}
			return `<div class="col-12"><table class="table js-sla-policy-template-table">
		<thead>
			<tr>
				<th></th>
				<th>${app.vtranslate('JS_POLICY_NAME')}</th>
				<th>${app.vtranslate('JS_OPERATIONAL_HOURS')}</th>
				<th>${app.vtranslate('JS_REACTION_TIME')}</th>
				<th>${app.vtranslate('JS_IDLE_TIME')}</th>
				<th>${app.vtranslate('JS_RESOLVE_TIME')}</th>
			</tr>
		</thead>
		<tbody>
		${rows
			.map((row) => {
				return `<tr>
				<td><input type="radio" name="policy_id" value="${row.id}"${row.checked ? 'checked="checked"' : ''}></td>
				<td>${row.name}</td>
				<td>${row.operational_hours}</td>
				<td>${row.reaction_time}</td>
				<td>${row.idle_time}</td>
				<td>${row.resolve_time}</td>
			</tr>`;
			})
			.join('')}
		</tbody>
		</table>
		</div>`;
		loadTemplates() {
			AppConnector.request({
				module: 'ServiceContracts',
				action: 'PolicyTemplatesAjax',
				targetModule: this.targetModule,
				record: Number($('#recordId').val())
			}).done((data) => {
				progress.progressIndicator({ mode: 'hide' });
				if (data.success) {
					this.container.find('.js-sla-policy-template--container').html(this.getTemplateTableHtml(data.result));
				}
				this.hideAll().showTemplateSettings().loadTemplates();
					$.each(this.container.find('.js-custom-row'), (index, rowElem) => {
				const index = this.container.find('.js-custom-row').length;
				const row = $(`<div class="card js-custom-row shadow-sm mb-2" data-id="0" data-record-id="` + addPolicyBtn.data('record-id') + `" 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">
								<label>${app.vtranslate('JS_BUSINESS_HOURS')}</label>
								<select class="select2" name="business_hours[${index}][]" multiple data-validation-engine="validate[required,funcCall[Vtiger_Base_Validator_Js.invokeValidation]]">
								${this.businessHours
									.map((businessHours) => {
										return `<option value="${businessHours.id}">${businessHours.name}</option>`;
									})
									.join('')}
								</select>
							</div>
							<div class="col-2 pr-2">
								<label>${app.vtranslate('JS_REACTION_TIME')}</label>
								<div class="input-group time">
									<input type="hidden" name="reaction_time[${index}]" class="c-time-period" value="1:d">
								</div>
							</div>
							<div class="col-2 pr-2">
								<label>${app.vtranslate('JS_IDLE_TIME')}</label>
								<div class="input-group time">
									<input type="hidden" name="idle_time[${index}]" class="c-time-period" value="1:d">
								</div>
							</div>
							<div class="col-2 pr-2">
								<label>${app.vtranslate('JS_RESOLVE_TIME')}</label>
								<div class="input-group time">
									<input type="hidden" name="resolve_time[${index}]" class="c-time-period" value="1:d">
								</div>
							</div>
						</div>
						<div class="row mt-2">
							<div class="js-conditions-col col">
								<input type="hidden" name="rowid[${index}]" value="0" class="js-custom-row-id" />
								<input type="hidden" name="conditions[${index}]" class="js-conditions-value" value="{}" data-js="container">
								${this.container.find('.js-conditions-template').html()}
							</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>
		</div>`
				);
				App.Fields.TimePeriod.register(row);
				this.registerDelBtnClick(row);
				App.Fields.Picklist.showSelect2ElementView(row.find('.select2'));
				this.registerConditionBuilder(
					row.find('.js-condition-builder').eq(0),
					this.container.find('.js-conditions-col').length
				);
				this.container.find('.js-custom-conditions').append(row);
				}).done((data) => {
			this.businessHours = JSON.parse(this.container.find('.js-all-business-hours').val());
			this.container.find('.js-sla-policy-type-radio').on('click', (e) => this.onPolicyTypeChange());
			app.event.on('DetailView.Tab.AfterLoad', (event, data, instance) => {

Fixed code:
	'appVersion' => '6.4.16',
	{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']|escape}">
								</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 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 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="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>
		{/if}
	{/foreach}
				<div class="js-custom-conditions" data-js="container">
					{include file=\App\Layout::getTemplatePath('CustomConditions.tpl', $MODULE_NAME)}
				</div>
{*<!-- {[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}
{*<!-- {[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}
							{\App\Language::translate('LBL_EDIT',$QUALIFIED_MODULE)} - {\App\Purifier::encodeHtml($RECORD->getName())}
								<input type="text" name="name" class="form-control" value="{\App\Purifier::encodeHtml($RECORD->getName())}" data-validation-engine="validate[required,maxSize[255]]">
										<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>
									<input type="hidden" name="reaction_time" class="c-time-period" value="{$RECORD->get('reaction_time')|escape}">
									<input type="hidden" name="idle_time" class="c-time-period" value="{$RECORD->get('idle_time')|escape}">
									<input type="hidden" name="resolve_time" class="c-time-period" value="{$RECORD->get('resolve_time')|escape}">
<?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);
	}
}
 * @author      Radosław Skrzypczak <r.skrzypczak@yetiforce.com>
		 * Get default params
		 * @returns {Object}
		getDefaultParam() {
			return {
				module: 'ServiceContracts',
				view: 'PolicyTemplatesAjax',
				targetModule: this.targetModule,
				record: Number($('#recordId').val())
			};
		 * @param {Object} param
		 * @returns
		loadTemplates(param) {
			return new Promise((resolve, _reject) => {
				AppConnector.request(param)
					.done((data) => {
						progress.progressIndicator({ mode: 'hide' });
						resolve(data);
					})
					.fail((e, t) => {
						progress.progressIndicator({ mode: 'hide' });
						app.errorLog(e, t);
						app.showNotify({
							text: app.vtranslate('JS_ERROR'),
							type: 'error'
						});
					});
				this.hideAll()
					.showTemplateSettings()
					.loadTemplates({ mode: 'slaPolicyTemplate', ...this.getDefaultParam() })
					.then((data) => {
						this.container.find('.js-sla-policy-template--container').html(data);
					});
					$.each(this.container.find('.js-custom-row'), (_index, rowElem) => {
				this.loadTemplates({
					mode: 'slaPolicyCustom',
					index: this.container.find('.js-custom-row').length,
					...this.getDefaultParam()
				}).then((data) => {
					let html = $(data);
					App.Fields.TimePeriod.register(html);
					this.registerDelBtnClick(html);
					App.Fields.Picklist.showSelect2ElementView(html.find('.select2'));
					this.registerConditionBuilder(
						html.find('.js-condition-builder').eq(0),
						this.container.find('.js-conditions-col').length
					);
					this.container.find('.js-custom-conditions').append(html);
				});
				}).done(() => {
			this.container.find('.js-sla-policy-type-radio').on('click', () => this.onPolicyTypeChange());
			app.event.on('DetailView.Tab.AfterLoad', (_event, _data, instance) => {