sync
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { createElement, Dropdown, Popup, showAlert, createIcon, DateSelector, showConfirm, Grid, OptionBase } from "../ui";
|
||||
import { createElement, Dropdown, Popup, showAlert, createIcon, DateSelector, showConfirm, Grid, OptionBase, createCheckbox } from "../ui";
|
||||
import { nullOrEmpty } from "../utility";
|
||||
import AssetSelector from "./assetSelector";
|
||||
|
||||
@@ -131,6 +131,11 @@ export default class AddWorkOrder extends OptionBase {
|
||||
* @private
|
||||
* @type {Dropdown}
|
||||
*/
|
||||
dropAssetStatus: null,
|
||||
/**
|
||||
* @private
|
||||
* @type {DateSelector}
|
||||
*/
|
||||
dropAssignedTo: null,
|
||||
/**
|
||||
* @private
|
||||
@@ -221,6 +226,18 @@ export default class AddWorkOrder extends OptionBase {
|
||||
Status: -1
|
||||
};
|
||||
}
|
||||
let assetstatus = el.dropAssetStatus.selected;
|
||||
if (assetstatus != null) {
|
||||
assetstatus = {
|
||||
AssetCustomStatus: assetstatus.Id,
|
||||
AssetCustomStatusType: assetstatus.Type,
|
||||
AssetCustomStatusName: assetstatus.Name
|
||||
};
|
||||
} else {
|
||||
assetstatus = {
|
||||
AssetCustomStatus: -1
|
||||
};
|
||||
}
|
||||
let machine = this._var.asset;
|
||||
if (machine == null) {
|
||||
showAlert(title, this.r('FLTL_00311', 'Asset cannot be empty.')).then(() => this._var.container.querySelector('.wo-asset>svg')?.focus());
|
||||
@@ -238,7 +255,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
AssignedTo: el.dropAssignedTo.selected?.IID ?? '',
|
||||
AdvisorId: el.dropAdvisor.selected?.Key ?? '',
|
||||
LocationId: el.dropLocation.selected?.ID || -1,
|
||||
DepartmentId: el.dropDepartment.selected?.Id || -1,
|
||||
DepartmentId: el.dropDepartment.checked?.Id || -1,
|
||||
AssetID: machine.Id,
|
||||
VIN: machine.VIN,
|
||||
AssetName: machine.DisplayName,
|
||||
@@ -250,7 +267,8 @@ export default class AddWorkOrder extends OptionBase {
|
||||
LaborCost: -1,
|
||||
HourlyRate: -1,
|
||||
InspectionTemplateId: -1,
|
||||
...status
|
||||
...status,
|
||||
...assetstatus
|
||||
};
|
||||
item.CustomerId = this._var.customer?.Id ?? -1;
|
||||
item.Contacts = this._var.contacts ?? [];
|
||||
@@ -259,19 +277,18 @@ export default class AddWorkOrder extends OptionBase {
|
||||
showAlert(title, this.r('FLTL_00602', 'Complaint is required.')).then(() => el.textComplaint.focus());
|
||||
return null;
|
||||
}
|
||||
item.MeterType = machine.OnRoad ? 'Odometer' : 'HourMeter';
|
||||
if (el.dropStatus.selected?.Completed) {
|
||||
if (!el.dateCompleted.element.validity.valid) {
|
||||
showAlert(title, this.r('FLTL_00613', 'Completed Date cannot be empty.')).then(() => el.dateCompleted.element.focus());
|
||||
return null;
|
||||
}
|
||||
if (machine.OnRoad) {
|
||||
item.MeterType = 'Odometer';
|
||||
if (nullOrEmpty(item.Odometer) || isNaN(item.Odometer) || item.Odometer < 0) {
|
||||
showAlert(title, this.r('FLTL_02044', 'Odometer format error.')).then(() => el.inputOdometer.focus());
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
item.MeterType = 'HourMeter';
|
||||
if (nullOrEmpty(item.HourMeter) || isNaN(item.HourMeter) || item.HourMeter < 0) {
|
||||
showAlert(title, this.r('FLTL_01516', 'Hour Meter format error.')).then(() => el.inputHours.focus());
|
||||
return null;
|
||||
@@ -284,6 +301,9 @@ export default class AddWorkOrder extends OptionBase {
|
||||
async show() {
|
||||
const option = this._option;
|
||||
const allowCustomer = option.allowCustomer === true;
|
||||
const allowCommunicate = option.allowCommunicate === true;
|
||||
const commReadOnly = option.commReadOnly === true;
|
||||
const msgVariables = option.msgVariables || [];
|
||||
const title = this.r('FLTL_02078', 'Open Work Order');
|
||||
const tabIndex = Math.max.apply(null, [...document.querySelectorAll('[tabindex]')].map(e => e.tabIndex ?? 0)) + 3;
|
||||
const textComplaint = createElement('textarea', textarea => {
|
||||
@@ -333,6 +353,16 @@ export default class AddWorkOrder extends OptionBase {
|
||||
{ value: 'Mile', text: this.r('FLTL_01922', 'Mile') },
|
||||
{ value: 'Kilometre', text: this.r('FLTL_01694', 'Kilometer') }
|
||||
]
|
||||
const dropAssetStatus = new Dropdown({
|
||||
tabIndex: tabIndex + 5,
|
||||
htmlTemplate: it => createElement('span', 'wo-color-line',
|
||||
createElement('em', em => em.style.backgroundColor = it.Color),
|
||||
createElement('label', label => label.innerText = it.Name)
|
||||
),
|
||||
search: true,
|
||||
textKey: 'Name',
|
||||
valueKey: 'Id'
|
||||
});
|
||||
const dropAssignedTo = new Dropdown({
|
||||
tabIndex: tabIndex + 10,
|
||||
selected: '',
|
||||
@@ -360,6 +390,18 @@ export default class AddWorkOrder extends OptionBase {
|
||||
valueKey: 'Id',
|
||||
textKey: 'Name'
|
||||
});
|
||||
const dropMSGVariables = new Dropdown({
|
||||
selected: -1,
|
||||
search: true,
|
||||
valueKey: 'Id',
|
||||
textKey: 'Name'
|
||||
});
|
||||
dropMSGVariables.source = msgVariables.map(v => { return { Id: v.Name, Name: v.Name }; });
|
||||
const textMessage = createElement('textarea', textarea => {
|
||||
textarea.className = 'ui-text wo-message';
|
||||
});
|
||||
const dropMSGVariablesElement = dropMSGVariables.create();
|
||||
dropMSGVariablesElement.style.width = '200px';
|
||||
|
||||
// save variables
|
||||
this._var.el = {
|
||||
@@ -370,6 +412,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
inputHours,
|
||||
inputOdometer,
|
||||
dropOdometerUnit,
|
||||
dropAssetStatus,
|
||||
dropAssignedTo,
|
||||
dropAdvisor,
|
||||
dropLocation,
|
||||
@@ -415,6 +458,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
el.inputOdometer.value = '';
|
||||
el.dropOdometerUnit.select('Mile');
|
||||
}
|
||||
el.dropAssetStatus.select(it.CustomStatus);
|
||||
}
|
||||
}
|
||||
this._var.asset = it;
|
||||
@@ -537,6 +581,11 @@ export default class AddWorkOrder extends OptionBase {
|
||||
patternValidation(inputOdometer, '\\d+\\.?\\d*'),
|
||||
dropOdometerUnit.create()
|
||||
),
|
||||
createElement('span', span => {
|
||||
span.className = 'wo-title';
|
||||
span.innerText = this.r('FLTL_03590', 'Asset Availability:');
|
||||
}),
|
||||
dropAssetStatus.create(),
|
||||
createElement('span', span => {
|
||||
span.className = 'wo-title';
|
||||
span.innerText = this.r('FLTL_00382', 'Assigned Tech:');
|
||||
@@ -606,7 +655,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
buttons: [
|
||||
{
|
||||
key: 'open',
|
||||
text: title,
|
||||
text: this.r('FLTL_00700', 'Create Work Order'),
|
||||
trigger: async () => {
|
||||
popup.loading = true;
|
||||
try {
|
||||
@@ -620,7 +669,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
return false;
|
||||
}
|
||||
const next = await showConfirm(title, this.r('FLTL_02992', 'The selected asset is hidden and a work order cannot be created.') + '\n\n' + this.r('FLTL_00999', 'Do you wish to "Un-Hide" the asset?'), [
|
||||
{ key: 'unhide', text: this.r('FLTL_03136', 'Unhide') },
|
||||
{ key: 'unhide', text: this.r('FLTL_03378', 'Yes') },
|
||||
{ key: 'cancel', text: this.r('FLTL_00502', 'Cancel Work Order') }
|
||||
]);
|
||||
if (next.result !== 'unhide') {
|
||||
@@ -672,10 +721,142 @@ export default class AddWorkOrder extends OptionBase {
|
||||
if (next !== 'create') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((item.Status == 100 || item.StatusType == 100)
|
||||
&& (item.AssetCustomStatus == 10 || item.AssetCustomStatusType == 10)) {
|
||||
let msgdiv = createElement('div', div => {
|
||||
div.style.minWidth = "300px";
|
||||
div.style.marginLeft = "50px";
|
||||
div.style.fontSize = "14px";
|
||||
let msghtml = this.r('FLTL_03591', 'Asset Availability is set to');
|
||||
msghtml += ' <b style="color:#3d7892;">' + item.AssetCustomStatusName + '</b>';
|
||||
msghtml += '<br/><br/>' + this.r('FLTL_03592', 'Would you like to update?');
|
||||
div.innerHTML = msghtml;
|
||||
}
|
||||
);
|
||||
const nextassetstatus = await showConfirm(title, msgdiv, [
|
||||
{ key: 'yes', text: this.r('FLTL_03378', 'Yes') },
|
||||
{ key: 'no', text: this.r('FLTL_01978', 'No') }
|
||||
]);
|
||||
if (nextassetstatus.result !== 'no') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const el = this._var.el;
|
||||
if (item.Status > 0 && item.CustomerId > 0 && item.StatusMessage && allowCommunicate && !commReadOnly) {
|
||||
const next = await new Promise(resolve => {
|
||||
let addButton;
|
||||
const chkSend = createCheckbox({
|
||||
label: this.r('FLTL_02700', 'Send Update To Customer'),
|
||||
onchange: () => {
|
||||
const chk = chkSend.querySelector('input');
|
||||
el.chkLink.querySelector('input').disabled = !chk.checked;
|
||||
el.txtMessage.disabled = !chk.checked;
|
||||
el.txtPhoneNumber.disabled = !chk.checked;
|
||||
dropMSGVariables.disabled = !chk.checked;
|
||||
addButton.disabled = !chk.checked;
|
||||
}
|
||||
});
|
||||
el.chkSend = chkSend;
|
||||
chkSend.style.paddingLeft = '0px';
|
||||
|
||||
const chkLink = createCheckbox({
|
||||
label: this.r('FLTL_01580', 'Include Status Link')
|
||||
});
|
||||
el.chkLink = chkLink;
|
||||
chkLink.style.paddingLeft = '0px';
|
||||
el.txtMessage = textMessage;
|
||||
|
||||
const iconmobile = createIcon('fa-solid', 'mobile-alt');
|
||||
const sPopup = new Popup({
|
||||
title: this.r('FLTL_02824', 'Status Change') + " - " + item.StatusName,
|
||||
content: createElement('div', 'wo-send-status-msg',
|
||||
createElement('label'),
|
||||
chkSend,
|
||||
createElement('div', div => {
|
||||
div.style.textAlign = 'right';
|
||||
div.style.paddingRight = '5px';
|
||||
div.appendChild(iconmobile);
|
||||
}),
|
||||
createElement('input', input => {
|
||||
input.type = 'text';
|
||||
el.txtPhoneNumber = input;
|
||||
}),
|
||||
createElement('label'),
|
||||
chkLink,
|
||||
createElement('label', label => {
|
||||
label.innerText = this.r('FLTL_01912', 'Message:');
|
||||
label.style.textAlign = 'right';
|
||||
label.style.paddingRight = '5px';
|
||||
}),
|
||||
createElement('div', div => {
|
||||
div.style.display = 'flex';
|
||||
div.style.alignItems = 'center';
|
||||
div.appendChild(dropMSGVariablesElement);
|
||||
addButton = createElement('input', input => {
|
||||
input.type = 'button';
|
||||
input.style.marginLeft = "10px";
|
||||
input.style.height = "24px";
|
||||
input.value = this.r('FLTL_00083', 'Add');
|
||||
})
|
||||
addButton.addEventListener('click', () => {
|
||||
const text = dropMSGVariables.selected?.Name;
|
||||
if (!text) return;
|
||||
textMessage.focus();
|
||||
const startPos = textMessage.selectionStart;
|
||||
const endPos = textMessage.selectionEnd;
|
||||
textMessage.value = textMessage.value.substring(0, startPos) + text + textMessage.value.substring(endPos, textMessage.value.length);
|
||||
textMessage.selectionStart = textMessage.selectionEnd = startPos + text.length;
|
||||
});
|
||||
div.appendChild(addButton);
|
||||
}),
|
||||
createElement('label'),
|
||||
textMessage
|
||||
),
|
||||
resolve,
|
||||
buttons: [
|
||||
{ key: 'ok', text: this.r('FLTL_02582', 'Save Work Order and Send'), trigger: () => resolve('ok') },
|
||||
{ key: 'cancel', text: this.r('FLTL_00499', 'Cancel'), trigger: () => resolve('cancel') }
|
||||
]
|
||||
});
|
||||
|
||||
var names = "";
|
||||
for (var i = 0; i < item.Contacts.length; i++) {
|
||||
var c = item.Contacts[i];
|
||||
if (c.OptOut || c.OptOut_BC) continue;
|
||||
var mp = $.trim(c.MobilePhone);
|
||||
var email = $.trim(c.Email);
|
||||
if ((c.ContactPreference == "0" && (checkPhoneNumber(mp))
|
||||
|| (c.ContactPreference == "1" && isEmail(email)))) {
|
||||
if (names == "")
|
||||
names = c.Name;
|
||||
else
|
||||
names += ";" + c.Name;
|
||||
}
|
||||
}
|
||||
el.txtPhoneNumber.value = names;
|
||||
el.chkSend.querySelector('input').checked = item.StatusAutoText;
|
||||
el.chkSend.querySelector('input').dispatchEvent(new Event('change'));
|
||||
el.txtMessage.value = item.StatusMessage;
|
||||
dropMSGVariables.select(dropMSGVariables.source[0].Name);
|
||||
|
||||
sPopup.show().then(mask => {
|
||||
});
|
||||
});
|
||||
if (next !== 'ok') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (typeof this.onSave === 'function') {
|
||||
this.onSave(item, this._var.el.dropStatus.selected);
|
||||
const sendStatusInfo = (item.Status > 0 && item.CustomerId > 0 && item.StatusMessage && el.chkSend) ? {
|
||||
SendUpdateToCustomer: el.chkSend.querySelector('input').checked,
|
||||
IncludeStatusLink: el.chkLink.querySelector('input').checked,
|
||||
PhoneEmails: el.txtPhoneNumber.value,
|
||||
Comment: el.txtMessage.value,
|
||||
} : null;
|
||||
this.onSave(item, sendStatusInfo);
|
||||
}
|
||||
} finally {
|
||||
popup.loading = false;
|
||||
@@ -692,6 +873,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
if (typeof option.requestWorkOrderParams === 'function') {
|
||||
popup.loading = true;
|
||||
const data = await option.requestWorkOrderParams()
|
||||
dropAssetStatus.source = data.AssetAvailabilities;
|
||||
if (!isNaN(data.AssetId) && data.AssetId > 0 && typeof option.requestAssetInfo === 'function') {
|
||||
const it = await option.requestAssetInfo(data.AssetId);
|
||||
if (it != null) {
|
||||
@@ -712,6 +894,7 @@ export default class AddWorkOrder extends OptionBase {
|
||||
dropAssignedTo.source = [{ IID: '', DisplayName: '' }, ...data];
|
||||
// dropStatus.onSelected(dropStatus.selected);
|
||||
}
|
||||
dropAssetStatus.select(it.CustomStatus);
|
||||
}
|
||||
}
|
||||
popup.loading = false;
|
||||
|
||||
Reference in New Issue
Block a user