re-factor / cleanup

This commit is contained in:
2022-01-11 22:08:38 +00:00
parent e871708b20
commit e0be8a7cfe
251 changed files with 14680 additions and 15693 deletions

View File

@@ -1325,7 +1325,11 @@ Current v8 docs home: https://www.ayanova.com/docs/
BUILD 8.0.0-beta.0.11 CHANGES OF NOTE
- Changed web app build process to remove support for "legacy" browsers now is set to only support browsers with > 1% usage and most recent two versions only
- Changed "Service" role translation to "Service manager" (and other languages equivalent)
- admin -> attachments not using correct icon, changed to paperclip from folder icon
- TODO BEFORE POST THIS UPDATE VUE AND ETC
- History form event "utility file downloaded" wasn't properly enabled, fixed
- refactor
*** TODO: check that about form properly shows user name and some other fields due to removing this. from template

View File

@@ -67,7 +67,8 @@
"node": true
},
"extends": [
"plugin:vue/strongly-recommended",
"plugin:vue/recommended",
"eslint:recommended",
"@vue/prettier"
],
"parserOptions": {

View File

@@ -31,9 +31,9 @@
<!-- TOP LEVEL HOLDER -->
<template v-if="!item.route">
<v-list-group
:key="item.key"
:prepend-icon="item.icon"
:value="false"
:key="item.key"
:data-cy="item.testid"
>
<template v-slot:activator>
@@ -45,12 +45,12 @@
<template v-for="subitem in item.navItems">
<template v-if="!subitem.route">
<!-- SECOND LEVEL HOLDER -->
<div class="pl-2" :key="subitem.key">
<div :key="subitem.key" class="pl-2">
<v-list-group
:key="subitem.key"
no-action
sub-group
:value="false"
:key="subitem.key"
>
<!-- Second level activator -->
<template v-slot:activator>
@@ -68,8 +68,8 @@
>
<v-list-item-action>
<v-icon
:color="item.color ? item.color : ''"
v-if="subsub.icon"
:color="item.color ? item.color : ''"
>{{ subsub.icon }}</v-icon
>
</v-list-item-action>
@@ -83,15 +83,15 @@
</template>
<template v-else>
<!-- SECOND LEVEL ACTION -->
<div class="pl-3" :key="subitem.key">
<div :key="subitem.key" class="pl-3">
<v-list-item
:to="subitem.route"
:data-cy="'nav' + subitem.testid"
>
<v-list-item-action>
<v-icon
:color="item.color ? item.color : ''"
v-if="subitem.icon"
:color="item.color ? item.color : ''"
>{{ subitem.icon }}</v-icon
>
</v-list-item-action>
@@ -138,8 +138,8 @@
</v-navigation-drawer>
<v-app-bar v-if="isAuthenticated" :color="appBar.color" dark fixed app>
<v-app-bar-nav-icon
@click.stop="drawer = !drawer"
data-cy="navicon"
@click.stop="drawer = !drawer"
></v-app-bar-nav-icon>
<v-toolbar-title class="ml-n5 ml-sm-0 pl-sm-4">
<v-icon>{{ appBar.icon }}</v-icon>
@@ -163,13 +163,13 @@
<v-toolbar-items>
<template v-for="item in appBar.menuItems">
<v-btn
v-if="item.surface"
:key="item.key"
class="hidden-xs-only"
icon
v-if="item.surface"
:disabled="item.disabled"
@click="clickMenuItem(item)"
:data-cy="item.key"
@click="clickMenuItem(item)"
>
<v-icon :color="item.color ? item.color : ''">
{{ item.icon }}
@@ -181,7 +181,7 @@
<v-menu float-left>
<template v-slot:activator="{ on }">
<v-btn text icon v-on="on" data-cy="contextmenu">
<v-btn text icon data-cy="contextmenu" v-on="on">
<v-icon>$ayiEllipsisV</v-icon>
</v-btn>
</template>
@@ -202,9 +202,9 @@
:disabled="item.disabled"
:href="item.href"
:target="item.target"
@click="clickMenuItem(item)"
:class="{ 'hidden-sm-and-up': item.surface }"
:data-cy="item.key"
@click="clickMenuItem(item)"
>
<v-list-item-action>
<v-icon
@@ -228,7 +228,7 @@
<v-main>
<v-container fluid class="my-8">
<transition name="fade" mode="out-in" @after-leave="afterLeave">
<router-view class="view" :key="$route.fullPath"></router-view>
<router-view :key="$route.fullPath" class="view"></router-view>
</transition>
</v-container>
</v-main>
@@ -245,6 +245,9 @@ export default {
gzconfirm,
gznotify
},
props: {
source: { type: String, default: null }
},
data() {
return {
drawer: null,
@@ -262,6 +265,23 @@ export default {
updateExists: false
};
},
computed: {
isAuthenticated() {
return this.$store.state.authenticated === true;
},
navItems() {
return this.$store.state.navItems;
},
helpUrl() {
return this.$store.state.helpUrl;
},
titleDisplay() {
if (this.appBar.title == null || this.appBar.title == "") {
return null;
}
return this.appBar.title;
}
},
async created() {
//Don't call this unless there is a service worker (https or localhost only, not private network) or else vuetify goes snakey and things start breaking
if (navigator.serviceWorker) {
@@ -346,26 +366,6 @@ export default {
//FUTURE: If need to detect a reload, this works reliably
//OK if here then is this a reliable way to detect a reload or refresh or re-open of the app from a closed window but still authenticated?
},
computed: {
isAuthenticated() {
return this.$store.state.authenticated === true;
},
navItems() {
return this.$store.state.navItems;
},
helpUrl() {
return this.$store.state.helpUrl;
},
titleDisplay() {
if (this.appBar.title == null || this.appBar.title == "") {
return null;
}
return this.appBar.title;
}
},
props: {
source: { type: String, default: null }
},
methods: {
afterLeave() {
this.$root.$emit("triggerScroll");

View File

@@ -3,6 +3,7 @@ import initialize from "./initialize";
import notifypoll from "./notifypoll";
export function processLogin(authResponse, loggedInWithKnownPassword) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async function(resolve, reject) {
try {
//check there is a response of some kind

View File

@@ -16,7 +16,7 @@ export default {
const availableRoles = this.getSelectionList("AuthorizationRoles");
for (let i = 0; i < availableRoles.length; i++) {
const role = availableRoles[i];
if (!!(enumValue & role.id)) {
if (enumValue & role.id) {
ret.push(role.name);
}
}
@@ -70,7 +70,7 @@ export default {
//enums is an object this is checking if that object has a key with the name in k
if (!window.$gz.util.has(window.$gz.store.state.enums, k)) {
const that = this;
// eslint-disable-next-line
const dat = await that.fetchEnumKey(k);
//massage the data as necessary
const e = { enumKey: k, items: {} };
@@ -84,10 +84,10 @@ export default {
}
},
async fetchEnumKey(enumKey) {
// eslint-disable-next-line
const res = await window.$gz.api.get("enum-list/list/" + enumKey);
//We never expect there to be no data here
if (!res.hasOwnProperty("data")) {
//if (!Object.prototype.hasOwnProperty.call(res, "data")) {
if (!Object.prototype.hasOwnProperty.call(res, "data")) {
return Promise.reject(res);
}
return res.data;

View File

@@ -32,6 +32,7 @@ async function dealWithError(msg, vm) {
// eslint-disable-next-line no-console
console.error(errMsg);
// eslint-disable-next-line no-debugger
debugger;
}
@@ -142,7 +143,7 @@ function decodeError(e, vm) {
//Javascript Fetch API Response object?
if (e instanceof Response) {
return `http error: ${err.statusText} - ${err.status} Url: ${err.url}`;
return `http error: ${e.statusText} - ${e.status} Url: ${e.url}`;
}
//last resort

View File

@@ -542,7 +542,7 @@ export default {
r = await that.extractBodyEx(r);
return r;
} catch (error) {
handleError("POSTATTACHMENT", error, route);
handleError("POSTATTACHMENT", error, "uploadAttachmentRoute");
}
},
//////////////////////////////////////////////
@@ -616,7 +616,7 @@ export default {
r = await that.extractBodyEx(r);
return r;
} catch (error) {
handleError("uploadLogo", error, route);
handleError("uploadLogo", error, "postLogoRoute");
}
},
///////////////////////////////////
@@ -633,7 +633,6 @@ export default {
LanguageName: window.$gz.locale.getResolvedLanguage(),
Hour12: window.$gz.locale.getHour12(),
CurrencyName: window.$gz.locale.getCurrencyName(),
LanguageName: window.$gz.locale.getResolvedLanguage(),
DefaultLocale: window.$gz.locale.getResolvedLanguage().split("-", 1)[0], //kind of suspect, maybe it can be removed
PDFDate: window.$gz.locale.utcDateToShortDateLocalized(nowUtc),
PDFTime: window.$gz.locale.utcDateToShortTimeLocalized(nowUtc)
@@ -646,7 +645,7 @@ export default {
async fetchBizObjectName(ayaType, objectId) {
const res = await this.get(`name/${ayaType}/${objectId}`);
//We never expect there to be no data here
if (!res.hasOwnProperty("data")) {
if (!Object.prototype.hasOwnProperty.call(res, "data")) {
return Promise.reject(res);
} else {
return res.data;

View File

@@ -239,9 +239,10 @@ export default {
vm: vm
});
*/
let key = null;
//Find the last report key and update it if present
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
var key = vm.appBar.menuItems[i].key;
key = vm.appBar.menuItems[i].key;
if (key && key.includes(":report:")) {
vm.appBar.menuItems[i].key = newItem.key;
vm.appBar.menuItems[i].title = newItem.title;
@@ -250,7 +251,7 @@ export default {
}
//No prior last report so slot it in under the report one
for (let i = 0; i < vm.appBar.menuItems.length; i++) {
var key = vm.appBar.menuItems[i].key;
key = vm.appBar.menuItems[i].key;
if (key && key.endsWith(":report")) {
vm.appBar.menuItems.splice(i + 1, 0, newItem);
}

View File

@@ -118,7 +118,7 @@ export default {
removeAllPropertiesFromObject: function(o) {
for (let variableKey in o) {
if (o.hasOwnProperty(variableKey)) {
if (Object.prototype.hasOwnProperty.call(o, variableKey)) {
delete o[variableKey];
}
}
@@ -136,7 +136,7 @@ export default {
if (
!key.endsWith("Viz") &&
!skipNames.some(x => x == key) &&
source.hasOwnProperty(key)
Object.prototype.hasOwnProperty.call(source, key)
) {
o[key] = source[key];
}
@@ -201,7 +201,7 @@ export default {
// ROUNDING
// //https://medium.com/swlh/how-to-round-to-a-certain-number-of-decimal-places-in-javascript-ed74c471c1b8
roundAccurately: function(number, decimalPlaces) {
if (!number || number == 0 || number == NaN) {
if (!number || number == 0 || Number.isNaN(number)) {
return number;
}
const wasNegative = number < 0;
@@ -300,7 +300,7 @@ export default {
//A number already then parse and return
if (this.isNumeric(string)) {
if (string === NaN) {
if (Number.isNaN(string)) {
return 0;
}
return parseFloat(string);
@@ -312,7 +312,7 @@ export default {
}
const ret = parseFloat(string.replace(/[^\d.-]/g, ""));
if (ret == NaN) {
if (Number.isNaN(ret)) {
return 0;
}
@@ -324,7 +324,7 @@ export default {
//
isNegative: function(v) {
//null or empty then zero
if (!v || v == 0 || v == NaN) {
if (!v || v == 0 || Number.isNaN(v)) {
return false;
}
return parseFloat(v) < 0;
@@ -943,25 +943,25 @@ export default {
const ret = [];
//turn EXCLUDE selected gzDaysOfWeek into INCLUDE selected days for vCalendar
if (!!!(dow & 64)) {
if (!(dow & 64)) {
ret.push(0);
}
if (!!!(dow & 1)) {
if (!(dow & 1)) {
ret.push(1);
}
if (!!!(dow & 2)) {
if (!(dow & 2)) {
ret.push(2);
}
if (!!!(dow & 4)) {
if (!(dow & 4)) {
ret.push(3);
}
if (!!!(dow & 8)) {
if (!(dow & 8)) {
ret.push(4);
}
if (!!!(dow & 16)) {
if (!(dow & 16)) {
ret.push(5);
}
if (!!!(dow & 32)) {
if (!(dow & 32)) {
ret.push(6);
}
return ret;

View File

@@ -862,8 +862,7 @@ async function getUserOptions() {
"logItem",
"Initialize::() fetch useroptions -> error" + error
);
// throw new Error(error);
throw new Error(window.$gz.errorHandler.errorToString(res));
throw new Error(window.$gz.errorHandler.errorToString(error));
}
}
@@ -871,6 +870,7 @@ async function getUserOptions() {
// Initialize the app
// on change of authentication status
export default function initialize() {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async function(resolve, reject) {
if (!window.$gz.store.state.authenticated) {
throw new Error("initialize: Error, called but user not authenticated!");

View File

@@ -453,12 +453,7 @@ export default {
///////////////////////////////////////////////
// Get default start date time in api format
// (this is used to centralize and for future)
defaultStartDateTime(ofType) {
//ofType in future could be for
//different areas having different custom start / top times
//so will set that in all callers for future purposes, but
//for now, here going to ignore it and just default to now
//and now plus one hour
defaultStartDateTime() {
return {
start: window.$gz.DateTime.local()
.toUTC()

View File

@@ -10,7 +10,7 @@ export default {
if (editedTranslation) {
//iterate the keys that are cached and set them from whatever is in editedTranslation for that key
for (const [key, value] of Object.entries(
for (const [key] of Object.entries(
window.$gz.store.state.translationText
)) {
const display = editedTranslation.translationItems.find(
@@ -55,6 +55,7 @@ export default {
return window.$gz.store.state.translationText[key];
},
async cacheTranslations(keys, forceTranslationId) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async function fetchTranslationKeysFromServer(resolve) {
//
//step 1: build an array of keys that we don't have already

View File

@@ -9,10 +9,6 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////
export default {
data() {
return {};
},
props: {
value: {
default: null,
@@ -27,6 +23,10 @@ export default {
readonly: Boolean,
disabled: Boolean
},
data() {
return {};
},
computed: {},
methods: {
form() {
@@ -37,7 +37,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {}
}
};
</script>

View File

@@ -2,9 +2,9 @@
<v-col v-if="alertMessage" cols="12" mt-1 mb-2>
<template v-if="popAlert">
<v-alert
v-show="alertMessage"
ref="alertBox"
data-cy="alertbox"
v-show="alertMessage"
color="accent"
type="error"
icon="$ayiExclamationTriangle"
@@ -15,9 +15,9 @@
>
<template v-else>
<v-alert
v-show="alertMessage"
ref="alertBox"
data-cy="alertbox"
v-show="alertMessage"
color="primary"
icon="$ayiInfoCircle"
class="multi-line"
@@ -29,10 +29,10 @@
</template>
<script>
export default {
data: () => ({}),
props: {
alertMessage: { type: String, default: null },
popAlert: { type: Boolean, default: false }
}
},
data: () => ({})
};
</script>

View File

@@ -1,9 +1,9 @@
<template>
<div class="mt-6" v-resize="onResize">
<div v-resize="onResize" class="mt-6">
<div>
<v-btn depressed tile @click="revealedClicked">
{{ $ay.t("Attachments")
}}<v-icon v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'" right></v-icon
}}<v-icon right v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"></v-icon
></v-btn>
</div>
@@ -52,12 +52,12 @@
<v-tab-item key="list">
<div
v-cloak
id="dropDiv"
class="mt-4"
:style="cardTextStyle()"
@drop.prevent="onDrop"
@dragover.prevent="onDragOver"
@dragleave="onDragEnd"
class="mt-4"
:style="cardTextStyle()"
id="dropDiv"
>
<span v-if="!hasFiles()">{{ $ay.t("DropFilesHere") }}</span>
<v-list three-line>
@@ -86,18 +86,18 @@
</v-list-item-content>
<v-list-item-action>
<v-btn large @click="openEditMenu(item, $event)" icon>
<v-btn large icon @click="openEditMenu(item, $event)">
<v-icon>$ayiEdit</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</div>
<v-btn depressed tile @click="revealedClicked" class="mt-8">
<v-btn depressed tile class="mt-8" @click="revealedClicked">
{{ $ay.t("Attachments")
}}<v-icon
v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"
right
v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"
></v-icon
></v-btn>
</v-tab-item>
@@ -123,8 +123,8 @@
</v-tabs-items>
</v-tabs>
<v-menu
min-width="360"
v-model="editMenu"
min-width="360"
:close-on-content-click="false"
offset-y
:position-x="menuX"
@@ -144,7 +144,7 @@
></v-text-field>
</div>
<v-card-actions>
<v-btn @click="remove()" text>
<v-btn text @click="remove()">
{{ $ay.t("Delete") }}
</v-btn>
<v-spacer v-if="!$vuetify.breakpoint.xs"></v-spacer>
@@ -164,6 +164,11 @@
</template>
<script>
export default {
props: {
ayaType: { type: Number, default: null },
ayaId: { type: Number, default: null },
readonly: Boolean
},
data() {
return {
reveal: false,
@@ -180,11 +185,6 @@ export default {
editId: null
};
},
props: {
ayaType: { type: Number, default: null },
ayaId: { type: Number, default: null },
readonly: Boolean
},
computed: {},
methods: {
revealedClicked() {
@@ -361,14 +361,14 @@ export default {
this.upload();
}
},
onDragOver(ev) {
onDragOver() {
if (!dropDiv) {
dropDiv = document.getElementById("dropDiv");
}
dropDiv.style.border = "4px dashed #00ff00";
},
onDragEnd(ev) {
onDragEnd() {
dropDiv.style.border = "none";
dropDiv = null;
}

View File

@@ -2,18 +2,18 @@
<div>
<v-text-field
ref="textField"
:value="currencyValue"
@input="updateValue"
v-currency="{
currency: currencyName,
locale: languageName
}"
:value="currencyValue"
:readonly="readonly"
:disabled="disabled"
:label="label"
:rules="rules"
:error-messages="errorMessages"
:append-outer-icon="appendOuterIcon"
@input="updateValue"
@click:append-outer="$emit('gz-append-outer')"
></v-text-field>
</div>
@@ -29,15 +29,8 @@
//which is purported to be exactly what I'm trying to do here with a v-text-field but better I guess??
//or look at the source for ideas?
import { setValue, parseCurrency } from "vue-currency-input";
import { parseCurrency } from "vue-currency-input";
export default {
data() {
return {
currencyName: window.$gz.locale.getCurrencyName(),
languageName: window.$gz.locale.getResolvedLanguage(),
initializing: true
};
},
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -47,6 +40,13 @@ export default {
errorMessages: { type: Array, default: null },
appendOuterIcon: { type: String, default: null }
},
data() {
return {
currencyName: window.$gz.locale.getCurrencyName(),
languageName: window.$gz.locale.getResolvedLanguage(),
initializing: true
};
},
computed: {
currencyValue() {
return this.value;

View File

@@ -13,11 +13,11 @@
<!-- DATETIME -->
<div v-if="item.type === 1">
<gz-date-time-picker
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -34,11 +34,11 @@
<!-- DATE -->
<div v-else-if="item.type === 2">
<gz-date-picker
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -54,11 +54,11 @@
<!-- TIME -->
<div v-else-if="item.type === 3">
<gz-time-picker
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -74,11 +74,11 @@
<!-- TEXT -->
<div v-else-if="item.type === 4">
<v-textarea
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -96,11 +96,11 @@
<!-- INTEGER -->
<div v-else-if="item.type === 5">
<v-text-field
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -120,11 +120,11 @@
<!-- BOOL -->
<div v-else-if="item.type === 6">
<v-checkbox
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -140,11 +140,11 @@
<!-- DECIMAL -->
<div v-else-if="item.type === 7">
<gz-decimal
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -160,11 +160,11 @@
<!-- CURRENCY -->
<div v-else-if="item.type === 8">
<gz-currency
:ref="item.fld"
v-model="_self[item.dataKey]"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t(item.tKey)"
:ref="item.fld"
:data-cy="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
@@ -190,10 +190,6 @@
</template>
<script>
export default {
data() {
return {};
},
props: {
value: {
default: "{}",
@@ -208,124 +204,8 @@ export default {
type: Object
}
},
methods: {
form() {
//nothing
return window.$gz.form;
},
fieldValueChanged(ref) {
if (
!this.parentVM.formState.loading &&
!this.parentVM.formState.readonly
) {
window.$gz.form.fieldValueChanged(this.parentVM, ref);
}
},
GetValueForField: function(dataKey) {
let cData = {};
//get the data out of the JSON string value
if (this.value != null) {
cData = JSON.parse(this.value);
}
//Custom field types can be changed by the user and cause old entered data to be invalid for that field type
//Here we need to take action if the data is of an incompatible type for the control field type and attempt to coerce or simply nullify if not co-ercable the data
// - CURRENT TEXT fields could handle any data so they don't need to be changed
// - CURRENT BOOL fields can only handle empty or true false so they would need to be set null
// - CURRENT TIME, DATE, DATETIME are pretty specific but all use a datetime string so any value not datetime like should be nulled
// - CURRENT NUMBER, CURRENCY are also pretty specific but easy to identify if not fully numeric and then sb nulled or attempt to convert then null if not
const ctrlType = this.$store.state.formCustomTemplate[this.formKey].find(
z => z.dataKey == dataKey
).type;
//First get current value for the data that came from the server
let ret = cData[dataKey];
//Only process if value is non-null since all control types can handle null
if (ret != null) {
//check types that matter
/*thes are all types, not necessarily all custom field types
NoType = 0,
DateTime = 1,
Date = 2,
Time = 3,
Text = 4,
Integer = 5,
Bool = 6,
Decimal = 7,
Currency = 8,
Tags = 9,
Enum = 10,
EmailAddress = 11,
HTTP = 12,
InternalId = 13,
MemorySize=14
*/
switch (ctrlType) {
//DateLike?
case 1:
case 2:
case 3:
//can it be parsed into a date using the same library as the components use?
if (!window.$gz.DateTime.fromISO(ret).isValid) {
ret = null;
}
break;
case 6:
//if it's not already a boolean
if (!window.$gz.util.isBoolean(ret)) {
//it's not a bool and it's not null, it came from some other data type,
//perhaps though, it's a truthy string so check for that before giving up and nulling
if (window.$gz.util.isString(ret)) {
ret = window.$gz.util.stringToBoolean(ret);
break;
}
if (ret === 1) {
ret = true;
break;
}
if (ret === 0) {
ret = false;
break;
}
}
break;
case 8:
case 7:
if (!window.$gz.util.isNumeric(ret)) {
ret = window.$gz.util.stringToFloat(ret);
break;
}
break;
}
}
return ret;
},
SetValueForField: function(dataKey, newValue) {
//Get the current data out of the json string value
//
let cData = {};
if (this.value != null) {
cData = JSON.parse(this.value);
}
if (!window.$gz.util.has(cData, dataKey)) {
cData[dataKey] = null;
}
//handle null or undefined
if (newValue === null || newValue === undefined) {
cData[dataKey] = null;
} else {
//then set item in the cData
cData[dataKey] = newValue.toString();
}
this.$emit("input", JSON.stringify(cData));
}
data() {
return {};
},
computed: {
availableCustomFields() {
@@ -474,6 +354,125 @@ export default {
this.SetValueForField("c16", newValue);
}
}
},
methods: {
form() {
//nothing
return window.$gz.form;
},
fieldValueChanged(ref) {
if (
!this.parentVM.formState.loading &&
!this.parentVM.formState.readonly
) {
window.$gz.form.fieldValueChanged(this.parentVM, ref);
}
},
GetValueForField: function(dataKey) {
let cData = {};
//get the data out of the JSON string value
if (this.value != null) {
cData = JSON.parse(this.value);
}
//Custom field types can be changed by the user and cause old entered data to be invalid for that field type
//Here we need to take action if the data is of an incompatible type for the control field type and attempt to coerce or simply nullify if not co-ercable the data
// - CURRENT TEXT fields could handle any data so they don't need to be changed
// - CURRENT BOOL fields can only handle empty or true false so they would need to be set null
// - CURRENT TIME, DATE, DATETIME are pretty specific but all use a datetime string so any value not datetime like should be nulled
// - CURRENT NUMBER, CURRENCY are also pretty specific but easy to identify if not fully numeric and then sb nulled or attempt to convert then null if not
const ctrlType = this.$store.state.formCustomTemplate[this.formKey].find(
z => z.dataKey == dataKey
).type;
//First get current value for the data that came from the server
let ret = cData[dataKey];
//Only process if value is non-null since all control types can handle null
if (ret != null) {
//check types that matter
/*thes are all types, not necessarily all custom field types
NoType = 0,
DateTime = 1,
Date = 2,
Time = 3,
Text = 4,
Integer = 5,
Bool = 6,
Decimal = 7,
Currency = 8,
Tags = 9,
Enum = 10,
EmailAddress = 11,
HTTP = 12,
InternalId = 13,
MemorySize=14
*/
switch (ctrlType) {
//DateLike?
case 1:
case 2:
case 3:
//can it be parsed into a date using the same library as the components use?
if (!window.$gz.DateTime.fromISO(ret).isValid) {
ret = null;
}
break;
case 6:
//if it's not already a boolean
if (!window.$gz.util.isBoolean(ret)) {
//it's not a bool and it's not null, it came from some other data type,
//perhaps though, it's a truthy string so check for that before giving up and nulling
if (window.$gz.util.isString(ret)) {
ret = window.$gz.util.stringToBoolean(ret);
break;
}
if (ret === 1) {
ret = true;
break;
}
if (ret === 0) {
ret = false;
break;
}
}
break;
case 8:
case 7:
if (!window.$gz.util.isNumeric(ret)) {
ret = window.$gz.util.stringToFloat(ret);
break;
}
break;
}
}
return ret;
},
SetValueForField: function(dataKey, newValue) {
//Get the current data out of the json string value
//
let cData = {};
if (this.value != null) {
cData = JSON.parse(this.value);
}
if (!window.$gz.util.has(cData, dataKey)) {
cData[dataKey] = null;
}
//handle null or undefined
if (newValue === null || newValue === undefined) {
cData[dataKey] = null;
} else {
//then set item in the cData
cData[dataKey] = newValue.toString();
}
this.$emit("input", JSON.stringify(cData));
}
}
};
</script>

View File

@@ -140,11 +140,6 @@
</template>
<script>
export default {
data() {
return {
timer: ""
};
},
props: {
id: {
type: String,
@@ -158,6 +153,19 @@ export default {
maxListItems: { type: Number, default: 10 },
icon: { type: String, default: "$ayiTachometer" }
},
data() {
return {
timer: ""
};
},
computed: {
hasAddUrl: function() {
return this.addUrl && this.addUrl != "";
},
translatedTitle() {
return this.$ay.t(this.title);
}
},
created() {
this.refresh();
if (this.updateFrequency > 0) {
@@ -169,14 +177,6 @@ export default {
beforeDestroy() {
clearInterval(this.timer);
},
computed: {
hasAddUrl: function() {
return this.addUrl && this.addUrl != "";
},
translatedTitle() {
return this.$ay.t(this.title);
}
},
methods: {
refresh: function() {
this.$emit("dash-refresh");

View File

@@ -4,9 +4,9 @@
:add-url="'widgets/0'"
:update-frequency="58000"
:count="23"
v-bind="$attrs"
@dash-refresh="loadData"
v-on="$listeners"
v-bind="$attrs"
>
<template slot="main">
<gz-chart-bar-horizontal
@@ -47,14 +47,14 @@ export default {
components: {
GzDash
},
props: {},
data() {
return {
obj: {}
};
},
props: {},
created() {},
computed: {},
created() {},
methods: {
loadData: function() {
this.obj = {

View File

@@ -3,9 +3,9 @@
icon="$ayiTools"
:add-url="'widgets/0'"
:update-frequency="0"
v-bind="$attrs"
@dash-refresh="loadData"
v-on="$listeners"
v-bind="$attrs"
>
<template slot="main">
<v-calendar
@@ -18,8 +18,8 @@
interval-width="45"
:events="events"
:event-color="getEventColor"
@click:event="showEvent"
:locale="languageName"
@click:event="showEvent"
></v-calendar>
</template>
</gz-dash>
@@ -30,17 +30,17 @@ export default {
components: {
GzDash
},
props: {},
data() {
return {
events: [],
languageName: window.$gz.locale.getResolvedLanguage()
};
},
props: {},
computed: {},
created() {
// this.loadData();
},
computed: {},
methods: {
loadData: function() {
const events = [];

View File

@@ -3,9 +3,9 @@
icon="$ayiSplotch"
:add-url="'widgets/0'"
:update-frequency="32000"
v-bind="$attrs"
@dash-refresh="loadData"
v-on="$listeners"
v-bind="$attrs"
>
<template slot="main">
<div class="ml-4 mt-1">
@@ -30,14 +30,14 @@ export default {
components: {
GzDash
},
props: {},
data() {
return {
obj: {}
};
},
props: {},
created() {},
computed: {},
created() {},
methods: {
loadData: function() {
this.obj = {

View File

@@ -4,10 +4,10 @@
:add-url="'widgets/0'"
:show-more-button="true"
:update-frequency="60000"
v-bind="$attrs"
@dash-refresh="getDataFromApi()"
@dash-more-click="moreClick()"
v-on="$listeners"
v-bind="$attrs"
>
<template slot="main">
<div class="ml-4 mt-1">
@@ -38,6 +38,9 @@ export default {
components: {
GzDash
},
props: {
maxListItems: { type: Number, default: 10 }
},
data() {
return {
obj: [],
@@ -45,11 +48,8 @@ export default {
languageName: window.$gz.locale.getResolvedLanguage()
};
},
props: {
maxListItems: { type: Number, default: 10 }
},
created() {},
computed: {},
created() {},
methods: {
moreClick() {
const LIST_FORM_KEY = "widget-list";

View File

@@ -1,9 +1,9 @@
<template>
<v-dialog
max-width="600px"
v-model="isVisible"
@keydown.esc="close()"
max-width="600px"
data-cy="dataTableFilterControl"
@keydown.esc="close()"
>
<v-card>
<v-card-title>{{ tableColumnData.text }}</v-card-title>
@@ -42,9 +42,9 @@
></gz-date-time-picker>
</div>
<v-btn
v-if="editItem.tempFilterToken != null"
large
block
v-if="editItem.tempFilterToken != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -77,9 +77,9 @@
:clearable="!formState.readOnly"
></v-text-field>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -112,9 +112,9 @@
type="number"
></v-text-field>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -130,12 +130,12 @@
prepend-icon="$ayiFilter"
></v-select>
<v-radio-group
v-model="editItem.tempFilterValue"
v-if="
editItem.tempFilterOperator != null &&
editItem.tempFilterOperator != '*NOVALUE*' &&
editItem.tempFilterOperator != '*HASVALUE*'
"
v-model="editItem.tempFilterValue"
row
>
<v-radio :label="$ay.t('False')" :value="false"></v-radio>
@@ -143,9 +143,9 @@
</v-radio-group>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -171,9 +171,9 @@
:clearable="!formState.readOnly"
></gz-decimal>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -198,9 +198,9 @@
:clearable="!formState.readOnly"
></gz-currency>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -222,9 +222,9 @@
></gz-tag-picker>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -245,9 +245,9 @@
></gz-role-picker>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -276,9 +276,9 @@
></v-select>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -302,9 +302,9 @@
:readonly="formState.readOnly"
></gz-duration-picker>
<v-btn
v-if="editItem.tempFilterOperator != null"
large
block
v-if="editItem.tempFilterOperator != null"
@click="addFilterCondition(editItem)"
><v-icon large>$ayiPlus</v-icon></v-btn
>
@@ -347,23 +347,23 @@
</template>
</v-card-text>
<v-card-actions>
<v-btn text @click="close()" color="primary">{{
<v-btn text color="primary" @click="close()">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer />
<v-btn
v-if="editItem.filter.items.length > 0"
text
@click="clearAllFilterConditions()"
color="primary"
@click="clearAllFilterConditions()"
>{{ $ay.t("Delete") }}</v-btn
>
<v-spacer />
<v-btn
:disabled="formState.dirty == false"
text
@click="saveAndExit()"
color="primary"
@click="saveAndExit()"
>{{ $ay.t("Save") }}</v-btn
>
</v-card-actions>
@@ -373,8 +373,10 @@
<script>
export default {
components: {},
async created() {
await initForm(this);
props: {
dataListKey: { type: String, default: null },
activeFilterId: { type: Number, default: null }
},
data: () => ({
isVisible: false,
@@ -407,10 +409,8 @@ export default {
serverError: {}
}
}),
props: {
dataListKey: { type: String, default: null },
activeFilterId: { type: Number, default: null }
async created() {
await initForm(this);
},
methods: {
async saveAndExit() {
@@ -457,7 +457,7 @@ export default {
this.activeFilter
);
if (res.error) {
throw new Error(window.$gz.errorHandler.errorToString(res, vm));
throw new Error(window.$gz.errorHandler.errorToString(res, this));
} else {
this.close({ refresh: true });
}
@@ -601,7 +601,7 @@ export default {
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
await fetchTranslatedText();
populateSelectionLists(vm);
await populateFieldDefinitions(vm);
}
@@ -647,7 +647,7 @@ async function fetchActiveFilter(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"Filter",
"GridFilterDialogAndRadioText",
@@ -1029,8 +1029,7 @@ function getDisplayForFilter(
valueDisplay = window.$gz.locale.decimalLocalized(filterValue);
break;
case 6: //BOOL translate
const tKey = filterValue ? "True" : "False";
valueDisplay = vm.$ay.t(tKey);
valueDisplay = vm.$ay.t(filterValue ? "True" : "False");
break;
case 10: //ENUM translate
valueDisplay = window.$gz.enums.get(enumType, filterValue);
@@ -1039,20 +1038,22 @@ function getDisplayForFilter(
valueDisplay = window.$gz.locale.durationLocalized(filterValue);
break;
case 17: //Authorization Roles
const availableRoles = window.$gz.enums.getSelectionList(
"AuthorizationRoles"
); //will already be cached from viewing datatable
const roles = filterValue;
const roleNames = [];
if (roles != null && roles != 0) {
for (let i = 0; i < availableRoles.length; i++) {
const role = availableRoles[i];
if (!!(roles & role.id)) {
roleNames.push(role.name);
{
const availableRoles = window.$gz.enums.getSelectionList(
"AuthorizationRoles"
); //will already be cached from viewing datatable
const roles = filterValue;
const roleNames = [];
if (roles != null && roles != 0) {
for (let i = 0; i < availableRoles.length; i++) {
const role = availableRoles[i];
if (roles & role.id) {
roleNames.push(role.name);
}
}
}
valueDisplay = roleNames.join(", ");
}
valueDisplay = roleNames.join(", ");
break;
default:
valueDisplay = filterValue;

View File

@@ -1,9 +1,9 @@
<template>
<v-dialog
max-width="600px"
v-model="isVisible"
@keydown.esc="close()"
max-width="600px"
data-cy="dataTableFilterManagerControl"
@keydown.esc="close()"
>
<v-card>
<v-card-title>{{ $ay.t("Filter") }} </v-card-title>
@@ -12,38 +12,38 @@
>
<v-card-text>
<v-text-field
:readonly="formState.readOnly"
v-model="activeFilter.name"
:readonly="formState.readOnly"
:label="$ay.t('GridFilterName')"
required
></v-text-field>
<v-checkbox
ref="public"
v-model="activeFilter.public"
:readonly="formState.readOnly"
:label="$ay.t('AnyUser')"
ref="public"
data-cy="public"
></v-checkbox>
</v-card-text>
<v-card-actions>
<v-btn text @click="close()" color="primary">{{
<v-btn text color="primary" @click="close()">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer />
<template v-if="isSelfOwned">
<v-btn text @click="deleteFilter()" color="primary">{{
<v-btn text color="primary" @click="deleteFilter()">{{
$ay.t("Delete")
}}</v-btn>
<v-spacer />
</template>
<v-btn text @click="saveAndExit(true)" color="primary">{{
<v-btn text color="primary" @click="saveAndExit(true)">{{
$ay.t("SaveACopy")
}}</v-btn>
<template v-if="activeFilter.defaultFilter == false && isSelfOwned">
<v-spacer />
<v-btn text @click="saveAndExit()" color="primary">{{
<v-btn text color="primary" @click="saveAndExit()">{{
$ay.t("Save")
}}</v-btn>
</template>
@@ -54,8 +54,9 @@
<script>
export default {
components: {},
async created() {
await initForm(this);
props: {
dataListKey: { type: String, default: null },
activeFilterId: { type: Number, default: null }
},
data: () => ({
isVisible: false,
@@ -84,9 +85,8 @@ export default {
serverError: {}
}
}),
props: {
dataListKey: { type: String, default: null },
activeFilterId: { type: Number, default: null }
async created() {
await initForm(this);
},
methods: {
async deleteFilter() {
@@ -186,8 +186,8 @@ export default {
/////////////////////////////////
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
async function initForm() {
await fetchTranslatedText();
}
////////////////////
@@ -206,7 +206,7 @@ async function fetchActiveFilter(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations(["GridFilterName", "AnyUser"]);
}
</script>

View File

@@ -1,9 +1,9 @@
<template>
<v-dialog
max-width="600px"
v-model="isVisible"
@keydown.esc="close()"
max-width="600px"
data-cy="dataTableMobileFilterColumnSelectorControl"
@keydown.esc="close()"
>
<v-list>
<v-subheader>{{ $ay.t("Filter") }}</v-subheader>

View File

@@ -2,20 +2,20 @@
<div>
<gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
<gz-data-table-filter
ref="dataTableFilter"
:data-list-key="dataListKey"
:active-filter-id="activeFilterId"
ref="dataTableFilter"
>
</gz-data-table-filter>
<gz-data-table-filter-manager
ref="dataTableFilterManager"
:data-list-key="dataListKey"
:active-filter-id="activeFilterId"
ref="dataTableFilterManager"
>
</gz-data-table-filter-manager>
<gz-data-table-mobile-filter-column-selector
:headers="headers"
ref="dataTableMobileFilterColumnSelector"
:headers="headers"
>
</gz-data-table-mobile-filter-column-selector>
<v-card>
@@ -25,7 +25,7 @@
<v-btn text @click="preFilterNav()">
<v-icon data-cy="clickThru">{{ preFilterMode.icon }}</v-icon>
</v-btn>
<span @click="preFilterNav()" class="text-h5">
<span class="text-h5" @click="preFilterNav()">
{{ preFilterMode.viz }}</span
>
<v-btn
@@ -44,12 +44,12 @@
item-text="name"
item-value="id"
:label="$ay.t('Filter')"
@input="selectedFilterChanged"
prepend-icon="$ayiEdit"
@click:prepend="editFilter()"
:append-outer-icon="clearFilterIcon()"
@click:append-outer="clearFilter(true)"
data-cy="selectSavedFilter"
@input="selectedFilterChanged"
@click:prepend="editFilter()"
@click:append-outer="clearFilter(true)"
>
</v-select>
</template>
@@ -61,8 +61,8 @@
</v-btn>
<v-btn
text
v-if="$vuetify.breakpoint.xs"
text
class="ml-12"
@click="mobileColumnFilterSelect"
>
@@ -79,8 +79,8 @@
</div>
</v-card-title>
<div
class="text-h5 ml-3 accent--text"
v-if="!loading && records.length < 1"
class="text-h5 ml-3 accent--text"
>
{{ $ay.t("NoData") }}
</div>
@@ -92,9 +92,9 @@
-->
<template v-if="$vuetify.breakpoint.smAndUp">
<v-data-table
v-model="selected"
:headers="headers"
:items="records"
v-model="selected"
:options.sync="dataTablePagingOptions"
:server-items-length="totalRecords"
:loading="loading"
@@ -120,8 +120,8 @@
<v-btn
v-if="h.flt"
icon
@click.stop="filter(h)"
class="ml-n4 mr-1"
@click.stop="filter(h)"
><v-icon :color="filterColor(h)">$ayiFilter</v-icon></v-btn
>
{{ h.text }}
@@ -299,9 +299,9 @@
-->
<template v-else>
<v-data-table
v-model="selected"
:headers="headers"
:items="records"
v-model="selected"
:options.sync="dataTablePagingOptions"
:server-items-length="totalRecords"
:loading="loading"
@@ -345,9 +345,9 @@
</template>
<v-list dense>
<v-list-item
two-line
v-for="c in item.columns"
:key="c.key"
two-line
>
<v-list-item-content>
<v-list-item-title>
@@ -519,6 +519,34 @@
//has duplicate values in it and should be unique in every row
const MAX_TEXT_COLUMN_LENGTH = 1024;
export default {
props: {
formKey: { type: String, default: null },
dataListKey: { type: String, default: null },
clientCriteria: {
type: String,
default: undefined
},
preFilterMode: {
type: Object,
default: null
},
showSelect: {
type: Boolean,
default: false
},
singleSelect: {
type: Boolean,
default: false
},
reload: {
type: Boolean,
default: false
},
ridColumnOpenable: {
type: Boolean,
default: true
}
},
data() {
return {
loading: true,
@@ -550,34 +578,6 @@ export default {
}
};
},
props: {
formKey: { type: String, default: null },
dataListKey: { type: String, default: null },
clientCriteria: {
type: String,
default: undefined
},
preFilterMode: {
type: Object,
default: null
},
showSelect: {
type: Boolean,
default: false
},
singleSelect: {
type: Boolean,
default: false
},
reload: {
type: Boolean,
default: false
},
ridColumnOpenable: {
type: Boolean,
default: true
}
},
watch: {
dataTablePagingOptions: {
async handler() {
@@ -645,6 +645,13 @@ export default {
}
}
},
async created() {
//get pick lists
const vm = this;
await initForm(vm);
vm.loading = false;
vm.getDataFromApi();
},
methods: {
ensureUrlFormat: function(u) {
if (u && u.length > 0) {
@@ -699,8 +706,8 @@ export default {
`data-list-filter/${this.activeFilterId}`
);
if (res.error) {
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
this.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(this);
} else {
await fetchSavedFilterList(this);
if (reloadData) {
@@ -747,7 +754,7 @@ export default {
const sortBy = [];
const sortDesc = [];
if (rsort != null) {
Object.keys(rsort).forEach((key, index) => {
Object.keys(rsort).forEach(key => {
//Pull column header name "value" from "fk"matching "key" here from this.headers columns.c0 etc here from this.headers see above method
const found = this.headers.find(z => z.fk == key);
if (found != null) {
@@ -961,13 +968,6 @@ export default {
});
}
}
},
async created() {
//get pick lists
const vm = this;
await initForm(vm);
vm.loading = false;
vm.getDataFromApi();
}
};
@@ -1161,24 +1161,25 @@ async function buildRecords(listData, columndefinitions, ridColumnOpenable) {
display = window.$gz.locale.durationLocalized(display, true); //duration localized with no seconds
break;
case 17: //Authorization Roles
if (availableRoles == null) {
availableRoles = window.$gz.enums.getSelectionList(
"AuthorizationRoles"
);
}
const roles = display;
const roleNames = [];
{
if (availableRoles == null) {
availableRoles = window.$gz.enums.getSelectionList(
"AuthorizationRoles"
);
}
const roles = display;
const roleNames = [];
if (roles != null && roles != 0) {
for (let i = 0; i < availableRoles.length; i++) {
const role = availableRoles[i];
if (!!(roles & role.id)) {
roleNames.push(role.name);
if (roles != null && roles != 0) {
for (let i = 0; i < availableRoles.length; i++) {
const role = availableRoles[i];
if (roles & role.id) {
roleNames.push(role.name);
}
}
}
display = roleNames.join(", ");
}
display = roleNames.join(", ");
break;
default:
//do nothing, allow it to stay as is (checkbox, plain text etc)

View File

@@ -7,20 +7,20 @@
<v-dialog v-model="dlgdate" width="300px">
<template v-slot:activator="{ on }">
<v-text-field
v-on="on"
prepend-icon="$ayiCalendarAlt"
@click:prepend="dlgdate = true"
:value="dateValue"
:label="label"
:rules="rules"
readonly
:error="!!hasErrors"
v-on="on"
@click:prepend="dlgdate = true"
></v-text-field>
</template>
<v-date-picker
:value="dateValue"
@input="updateDateValue"
:locale="languageName"
@input="updateDateValue"
>
<v-btn text color="primary" @click="$emit('input', null)">{{
$ay.t("Delete")
@@ -43,7 +43,6 @@
<v-text-field
ref="dateField"
:value="dateValue"
@change="updateDateValue"
:readonly="readonly"
:disabled="disabled"
:label="label"
@@ -51,6 +50,7 @@
type="date"
:error-messages="errorMessages"
:data-cy="`${dataCy}:time`"
@change="updateDateValue"
></v-text-field>
</v-col>
</template>
@@ -76,11 +76,6 @@
<script>
//******************************** NOTE: this control also captures the TIME even though it's DATE only, this is an intentional design decision to support field change to date or date AND time and is considered a display issue */
export default {
data: () => ({
dlgdate: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage()
}),
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -90,6 +85,11 @@ export default {
disabled: { type: Boolean, default: false },
dataCy: { type: String, default: null }
},
data: () => ({
dlgdate: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage()
}),
computed: {
hasErrors() {
return this.errorMessages != null && this.errorMessages.length > 0;

View File

@@ -8,20 +8,20 @@
<v-dialog v-model="dlgdate" width="300px">
<template v-slot:activator="{ on }">
<v-text-field
v-on="on"
prepend-icon="$ayiCalendarAlt"
@click:prepend="dlgdate = true"
:value="dateValue"
:label="label"
:rules="rules"
readonly
:error="!!hasErrors"
v-on="on"
@click:prepend="dlgdate = true"
></v-text-field>
</template>
<v-date-picker
:value="dateValue"
@input="updateDateValue"
:locale="languageName"
@input="updateDateValue"
>
<v-btn text color="primary" @click="$emit('input', null)">{{
$ay.t("Delete")
@@ -41,13 +41,13 @@
<v-dialog v-model="dlgtime" width="300px">
<template v-slot:activator="{ on }">
<v-text-field
v-on="on"
:value="readonlyTimeFormat()"
label
prepend-icon="$ayiClock"
@click:prepend="dlgtime = true"
readonly
:error="!!hasErrors"
v-on="on"
@click:prepend="dlgtime = true"
></v-text-field>
</template>
<v-time-picker
@@ -77,7 +77,6 @@
<v-text-field
ref="dateField"
:value="dateValue"
@change="updateDateValue"
:readonly="readonly"
:disabled="disabled"
:label="label"
@@ -85,17 +84,18 @@
type="date"
:error-messages="errorMessages"
:data-cy="`${dataCy}:date`"
@change="updateDateValue"
></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field
ref="timeField"
:value="timeValue"
@change="updateTimeValue"
:readonly="readonly"
:disabled="disabled"
type="time"
:data-cy="`${dataCy}:time`"
@change="updateTimeValue"
></v-text-field>
</v-col>
</template>
@@ -121,14 +121,6 @@
</template>
<script>
export default {
data: () => ({
nativeInput: true,
dlgdate: false,
dlgtime: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
}),
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -138,6 +130,14 @@ export default {
disabled: { type: Boolean, default: false },
dataCy: { type: String, default: null }
},
data: () => ({
nativeInput: true,
dlgdate: false,
dlgtime: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
}),
computed: {
hasErrors() {
return this.errorMessages != null && this.errorMessages.length > 0;

View File

@@ -7,13 +7,13 @@
chips
deletable-chips
:value="selectedValue"
@input="handleInput"
:readonly="readonly"
:disabled="disabled"
:label="label"
:rules="rules"
:error-messages="errorMessages"
:data-cy="'dayinput:' + testId"
@input="handleInput"
></v-select>
</template>
<script>
@@ -21,16 +21,6 @@
//https://stackoverflow.com/a/24174625/8939
export default {
async created() {
await window.$gz.enums.fetchEnumList("AyaDaysOfWeek");
this.daysOfWeek = window.$gz.enums.getSelectionList("AyaDaysOfWeek", true);
},
data() {
return {
internalValue: null,
daysOfWeek: []
};
},
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -40,13 +30,19 @@ export default {
disabled: { type: Boolean, default: false },
testId: { type: String, default: null }
},
data() {
return {
internalValue: null,
daysOfWeek: []
};
},
computed: {
selectedValue() {
const ret = [];
if (this.value != null && this.value != 0) {
for (let i = 0; i < this.daysOfWeek.length; i++) {
const day = this.daysOfWeek[i];
if (!!(this.value & day.id)) {
if (this.value & day.id) {
ret.push(day.id);
}
}
@@ -54,6 +50,10 @@ export default {
return ret;
}
},
async created() {
await window.$gz.enums.fetchEnumList("AyaDaysOfWeek");
this.daysOfWeek = window.$gz.enums.getSelectionList("AyaDaysOfWeek", true);
},
methods: {
handleInput(value) {
let newValue = 0;

View File

@@ -2,18 +2,18 @@
<div>
<v-text-field
ref="textField"
:value="currencyValue"
@input="updateValue"
v-currency="{
currency: null,
locale: languageName,
precision: precision
}"
:value="currencyValue"
:readonly="readonly"
:disabled="disabled"
:label="label"
:rules="rules"
:error-messages="errorMessages"
@input="updateValue"
></v-text-field>
</div>
</template>
@@ -23,13 +23,8 @@
//https://codesandbox.io/s/vue-template-kd7d1?fontsize=14&module=%2Fsrc%2FApp.vue
//https://github.com/dm4t2/vue-currency-input
//https://github.com/dm4t2/vue-currency-input/releases
import { setValue, parseCurrency } from "vue-currency-input";
import { parseCurrency } from "vue-currency-input";
export default {
data() {
return {
languageName: window.$gz.locale.getResolvedLanguage()
};
},
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -39,6 +34,11 @@ export default {
errorMessages: { type: Array, default: null },
precision: { type: Number, default: undefined }
},
data() {
return {
languageName: window.$gz.locale.getResolvedLanguage()
};
},
computed: {
currencyValue() {
return this.value;

View File

@@ -10,53 +10,53 @@
v-show="showDays"
ref="daysPicker"
:value="splitSpan.days"
@input="updateSpan()"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t('TimeSpanDays')"
type="number"
:data-cy="`${dataCy}:days`"
:error="!!hasErrors"
@input="updateSpan()"
></v-text-field>
</v-col>
<v-col cols="3">
<v-text-field
:value="splitSpan.hours"
ref="hoursPicker"
@input="updateSpan()"
:value="splitSpan.hours"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t('TimeSpanHours')"
type="number"
:data-cy="`${dataCy}:hours`"
:error="!!hasErrors"
@input="updateSpan()"
></v-text-field>
</v-col>
<v-col cols="3">
<v-text-field
:value="splitSpan.minutes"
ref="minutesPicker"
@input="updateSpan()"
:value="splitSpan.minutes"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t('TimeSpanMinutes')"
type="number"
:data-cy="`${dataCy}:minutes`"
:error="!!hasErrors"
@input="updateSpan()"
></v-text-field>
</v-col>
<v-col cols="3">
<v-text-field
v-show="showSeconds"
:value="splitSpan.seconds"
ref="secondsPicker"
@input="updateSpan()"
:value="splitSpan.seconds"
:readonly="readonly"
:disabled="disabled"
:label="$ay.t('TimeSpanSeconds')"
type="number"
:data-cy="`${dataCy}:seconds`"
:error="!!hasErrors"
@input="updateSpan()"
></v-text-field>
</v-col>
</v-row>

View File

@@ -1,9 +1,9 @@
<template>
<v-text-field
v-bind="$attrs"
v-on="$listeners"
type="email"
prepend-icon="$ayiAt"
v-on="$listeners"
@click:prepend="openUrl"
></v-text-field>
</template>

View File

@@ -1,9 +1,9 @@
<template>
<v-col v-if="errorBoxMessage" cols="12" mt-1 mb-2>
<v-alert
v-show="errorBoxMessage"
ref="generalerror"
data-cy="generalerror"
v-show="errorBoxMessage"
color="error"
icon="$ayiExclamationTriangle"
class="multi-line"
@@ -14,9 +14,9 @@
</template>
<script>
export default {
data: () => ({}),
props: {
errorBoxMessage: { type: String, default: null }
}
},
data: () => ({})
};
</script>

View File

@@ -15,8 +15,8 @@
:disabled="!canDoAction()"
color="blue darken-1"
text
@click="doAction()"
:loading="jobActive"
@click="doAction()"
>{{ $ay.t("StartJob") }}</v-btn
>
</v-expansion-panel-content>
@@ -24,9 +24,17 @@
</template>
<script>
export default {
props: {
dataListSelection: { type: Object, default: null }
},
data: () => ({
jobActive: false,
rights: window.$gz.role.defaultRightsObject(),
available: false
}),
async created() {
const vm = this;
await fetchTranslatedText(vm);
await fetchTranslatedText();
//NOTE: if extension doesn't support a particular object add it here to the NoType default
if (
vm.dataListSelection.AType != 0 &&
@@ -36,11 +44,6 @@ export default {
}
vm.available = vm.rights.change;
},
data: () => ({
jobActive: false,
rights: window.$gz.role.defaultRightsObject(),
available: false
}),
methods: {
goHelp() {
window.open(this.$store.state.helpUrl + "ay-ex-delete", "_blank");
@@ -107,9 +110,6 @@ export default {
window.$gz.eventBus.$emit("notify-error", vm.$ay.t("JobFailed"));
}
}
},
props: {
dataListSelection: { type: Object, default: null }
}
};
@@ -117,7 +117,7 @@ export default {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"EraseMultipleObjectsWarning"
]);

View File

@@ -20,6 +20,9 @@
</template>
<script>
export default {
props: {
dataListSelection: { type: Object, default: null }
},
data: () => ({
exportFormat: "json",
jobActive: false
@@ -58,9 +61,6 @@ export default {
window.$gz.eventBus.$emit("notify-error", this.$ay.t("JobFailed"));
}
}
},
props: {
dataListSelection: { type: Object, default: null }
}
};
</script>

View File

@@ -19,12 +19,12 @@
></v-text-field>
</v-col>
<v-col cols="12" v-if="action == 'Replace'">
<v-col v-if="action == 'Replace'" cols="12">
<v-text-field
:value="replace"
:label="$ay.t('Replace')"
@input="normalizeReplace"
required
@input="normalizeReplace"
></v-text-field>
</v-col>
</v-row>
@@ -33,8 +33,8 @@
:disabled="!canDoAction()"
color="blue darken-1"
text
@click="doAction()"
:loading="jobActive"
@click="doAction()"
>{{ $ay.t("StartJob") }}</v-btn
>
</v-expansion-panel-content>
@@ -42,6 +42,17 @@
</template>
<script>
export default {
props: {
dataListSelection: { type: Object, default: null }
},
data: () => ({
action: "Add",
tag: null,
replace: null,
jobActive: false,
rights: window.$gz.role.defaultRightsObject(),
available: false
}),
created() {
const vm = this;
@@ -53,14 +64,6 @@ export default {
}
vm.available = vm.rights.change;
},
data: () => ({
action: "Add",
tag: null,
replace: null,
jobActive: false,
rights: window.$gz.role.defaultRightsObject(),
available: false
}),
methods: {
goHelp() {
window.open(this.$store.state.helpUrl + "ay-ex-tags", "_blank");
@@ -134,8 +137,11 @@ export default {
value = value.split(" ").join("-");
//Remove multiple dash sequences
value = value.replace(/-+/g, "-");
//Ensure doesn't start or end with a dash
value = value.replace(/^\-+-\-+$/g, "");
//linter says this is an unnecessary escape character so going with it but if issues with tag normalization here's maybe the culprit
//value = value.replace(/^\-+-\-+$/g, "");
value = value.replace(/^-+--+$/g, "");
return value;
},
normalizeTag(value) {
@@ -146,9 +152,6 @@ export default {
value = this.normalize(value);
this.replace = value;
}
},
props: {
dataListSelection: { type: Object, default: null }
}
};
</script>

View File

@@ -25,14 +25,14 @@
<ExtensionTags :data-list-selection="dataListSelection" />
<ExtensionExport :data-list-selection="dataListSelection" />
<ExtensionDelete
:data-list-selection="dataListSelection"
@ext-close-refresh="close({ refresh: true })"
@ext-show-job-log="handleError($event)"
:data-list-selection="dataListSelection"
/>
</v-expansion-panels>
</v-card-text>
<v-card-actions>
<v-btn text @click="close()" color="primary">{{
<v-btn text color="primary" @click="close()">{{
$ay.t("Close")
}}</v-btn>
</v-card-actions>
@@ -50,9 +50,6 @@ export default {
ExtensionExport,
ExtensionDelete
},
async created() {
await initForm(this);
},
data: () => ({
isVisible: false,
resolve: null,
@@ -68,6 +65,9 @@ export default {
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
}),
async created() {
await initForm(this);
},
methods: {
titleText() {
if (this.dataListSelection.selectedRowIds.length < 1) {
@@ -141,7 +141,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations(["TimeStamp", "ID", "Status"]);
}

View File

@@ -1,12 +1,12 @@
<template>
<div class="text-center">
<v-dialog
persistent
v-model="isVisible"
persistent
:max-width="maxWidth"
:width="width"
@keydown.esc="cancel"
data-cy="gzconfirm"
@keydown.esc="cancel"
>
<v-card elevation="24">
<v-card-title class="text-h6 text-sm-h5 grey lighten-4">
@@ -37,9 +37,9 @@
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
v-if="options.helpUrl"
data-cy="gzconfirm:morebutton"
text
v-if="options.helpUrl"
@click="helpClick()"
>
{{ this.$root.$gz.translation.get("More") }}
@@ -48,15 +48,15 @@
v-if="options.noButtonText"
color="primary"
text
@click.native="cancel"
data-cy="gzconfirm:nobutton"
@click.native="cancel"
>{{ options.noButtonText }}</v-btn
>
<v-btn
color="primary"
text
@click.native="agree"
data-cy="gzconfirm:yesbutton"
@click.native="agree"
>{{ options.yesButtonText }}</v-btn
>
</v-card-actions>

View File

@@ -10,9 +10,9 @@
</v-alert>
<v-btn
v-if="currentNotification.helpUrl"
data-cy="gznotify:morebutton"
text
v-if="currentNotification.helpUrl"
@click="helpClick()"
>
{{ this.$root.$gz.translation.get("More") }}

View File

@@ -2,19 +2,19 @@
<div>
<v-text-field
ref="textField"
:value="currencyValue"
@input="updateValue"
v-currency="{
currency: null,
locale: languageName,
precision: precision
}"
:value="currencyValue"
:readonly="readonly"
:disabled="disabled"
:label="label"
:rules="rules"
:error-messages="errorMessages"
append-icon="$ayiPercent"
@input="updateValue"
></v-text-field>
</div>
</template>
@@ -24,13 +24,8 @@
//https://codesandbox.io/s/vue-template-kd7d1?fontsize=14&module=%2Fsrc%2FApp.vue
//https://github.com/dm4t2/vue-currency-input
//https://github.com/dm4t2/vue-currency-input/releases
import { setValue, parseCurrency } from "vue-currency-input";
import { parseCurrency } from "vue-currency-input";
export default {
data() {
return {
languageName: window.$gz.locale.getResolvedLanguage()
};
},
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -40,6 +35,11 @@ export default {
errorMessages: { type: Array, default: null },
precision: { type: Number, default: 3 }
},
data() {
return {
languageName: window.$gz.locale.getResolvedLanguage()
};
},
computed: {
currencyValue() {
return this.value;

View File

@@ -1,9 +1,9 @@
<template>
<v-text-field
v-bind="$attrs"
v-on="$listeners"
type="tel"
prepend-icon="$ayiPhoneAlt"
v-on="$listeners"
@click:prepend="openUrl"
></v-text-field>
</template>

View File

@@ -2,7 +2,6 @@
<div>
<v-autocomplete
:value="value"
@input="selectionMade($event)"
:readonly="readonly"
:disabled="disabled"
return-object
@@ -23,10 +22,11 @@
:clearable="!readonly && canClear"
:no-filter="isTagFilter"
:append-icon="errorIcon"
@input="selectionMade($event)"
@click:append="handleErrorClick"
@mousedown="dropdown"
>
<template v-slot:prepend-item v-if="hasError()">
<template v-if="hasError()" v-slot:prepend-item>
<div class="pl-2">
<span class="error--text"> {{ entryError }}</span>
</div>
@@ -40,21 +40,6 @@
</template>
<script>
export default {
created() {
this.fetchValueIfNotPresent();
},
data() {
return {
searchResults: [],
entryError: null,
searchEntry: null,
lastSelection: null,
fetching: false,
isTagFilter: false,
errorIcon: null,
initialized: false
};
},
props: {
value: {
type: Number,
@@ -95,6 +80,18 @@ export default {
default: null
}
},
data() {
return {
searchResults: [],
entryError: null,
searchEntry: null,
lastSelection: null,
fetching: false,
isTagFilter: false,
errorIcon: null,
initialized: false
};
},
watch: {
ayaType(val, oldVal) {
if (val != oldVal && oldVal != null) {
@@ -105,10 +102,10 @@ export default {
this.initialized = false;
}
},
value(val) {
value() {
this.fetchValueIfNotPresent();
},
searchEntry(val, oldVal) {
searchEntry(val) {
this.clearErrors();
//if the search entry is in the results list then it's a drop down selection not a typed search so bail
for (let i = 0; i < this.searchResults.length; i++) {
@@ -126,7 +123,7 @@ export default {
}
this.doSearch(val);
},
entryError(val) {
entryError() {
if (this.hasError()) {
this.errorIcon = "$ayiQuestionCircle";
} else {
@@ -134,6 +131,9 @@ export default {
}
}
},
created() {
this.fetchValueIfNotPresent();
},
methods: {
//Get full selection for use on forms where we need the
//full selection including name, active, id
@@ -232,7 +232,7 @@ export default {
//Not there so insert it
this.searchResults.push(this.lastSelection);
},
dropdown(e) {
dropdown() {
const vm = this;
//check if we have only the initial loaded item and no selection item
if (vm.searchResults.length < 3) {
@@ -240,7 +240,7 @@ export default {
vm.getList();
}
},
customFilter(item, queryText, itemText) {
customFilter(item, queryText) {
//NOTE: I wanted this to work with tags but all it does is highlight all of each row if tag query is present
//I guess because it later on attempts to do the highlighting and can't find all the entered query
//it's not clean so I'm just going to make it only highlight if it's a non tag query for now
@@ -286,7 +286,7 @@ export default {
);
this.fetching = false;
if (!res.hasOwnProperty("data")) {
if (!Object.prototype.hasOwnProperty.call(res, "data")) {
return Promise.reject(res);
}
this.searchResults = res.data;

View File

@@ -2,17 +2,17 @@
<div>
<v-row>
<v-col
v-if="value.serial != 0 && canEditSerial"
cols="12"
sm="6"
lg="4"
xl="3"
v-if="value.serial != 0 && canEditSerial"
>
<v-text-field
ref="serial"
v-model="value.serial"
:readonly="formState.readOnly"
:label="$ay.t('PMSerialNumber')"
ref="serial"
data-cy="serial"
:rules="[
form().integerValid(this, 'serial'),
@@ -24,13 +24,13 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="customerId"
v-model="value.customerId"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.customerId"
:readonly="formState.readOnly || value.userIsRestrictedType"
:label="$ay.t('Customer')"
:can-clear="false"
ref="customerId"
data-cy="customerId"
:rules="[form().required(this, 'customerId')]"
:error-messages="form().serverErrors(this, 'customerId')"
@@ -62,25 +62,25 @@
<v-row>
<v-col cols="5">
<v-text-field
ref="repeatInterval"
v-model="value.repeatInterval"
:readonly="formState.readOnly"
:label="$ay.t('RepeatInterval')"
ref="repeatInterval"
data-cy="repeatInterval"
:rules="[form().integerValid(this, 'repeatInterval')]"
:error-messages="form().serverErrors(this, 'repeatInterval')"
@input="fieldValueChanged('repeatInterval')"
type="number"
@input="fieldValueChanged('repeatInterval')"
></v-text-field>
</v-col>
<v-col cols="5">
<v-select
:ref="`repeatUnit`"
v-model="value.repeatUnit"
:items="pvm.selectLists.pmTimeUnits"
item-text="name"
item-value="id"
:readonly="formState.readOnly"
:ref="`repeatUnit`"
data-cy="usertype"
:rules="[form().integerValid(this, `repeatUnit`)]"
:error-messages="form().serverErrors(this, `repeatUnit`)"
@@ -94,27 +94,27 @@
<v-row>
<v-col cols="5">
<v-text-field
ref="generateBeforeInterval"
v-model="value.generateBeforeInterval"
:readonly="formState.readOnly"
:label="$ay.t('GenerateBefore')"
ref="generateBeforeInterval"
data-cy="generateBeforeInterval"
:rules="[form().integerValid(this, 'generateBeforeInterval')]"
:error-messages="
form().serverErrors(this, 'generateBeforeInterval')
"
@input="fieldValueChanged('generateBeforeInterval')"
type="number"
@input="fieldValueChanged('generateBeforeInterval')"
></v-text-field>
</v-col>
<v-col cols="5">
<v-select
:ref="`generateBeforeUnit`"
v-model="value.generateBeforeUnit"
:items="pvm.selectLists.pmTimeUnits"
item-text="name"
item-value="id"
:readonly="formState.readOnly"
:ref="`generateBeforeUnit`"
data-cy="usertype"
:rules="[form().integerValid(this, `generateBeforeUnit`)]"
:error-messages="form().serverErrors(this, `generateBeforeUnit`)"
@@ -126,10 +126,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<GZDaysOfWeek
:label="$ay.t('ExcludeDaysOfWeek')"
v-model="value.excludeDaysOfWeek"
:readonly="formState.readOnly"
ref="excludeDaysOfWeek"
v-model="value.excludeDaysOfWeek"
:label="$ay.t('ExcludeDaysOfWeek')"
:readonly="formState.readOnly"
data-cy="excludeDaysOfWeek"
:error-messages="form().serverErrors(this, 'excludeDaysOfWeek')"
@input="fieldValueChanged('excludeDaysOfWeek')"
@@ -138,10 +138,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-date-time-picker
:label="$ay.t('PMNextServiceDate')"
v-model="value.nextServiceDate"
:readonly="formState.readOnly"
ref="nextServiceDate"
v-model="value.nextServiceDate"
:label="$ay.t('PMNextServiceDate')"
:readonly="formState.readOnly"
data-cy="nextServiceDate"
:rules="[form().required(this, 'nextServiceDate')]"
:error-messages="form().serverErrors(this, 'nextServiceDate')"
@@ -151,10 +151,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-date-time-picker
:label="$ay.t('PMStopGeneratingDate')"
v-model="value.stopGeneratingDate"
:readonly="formState.readOnly"
ref="stopGeneratingDate"
v-model="value.stopGeneratingDate"
:label="$ay.t('PMStopGeneratingDate')"
:readonly="formState.readOnly"
data-cy="stopGeneratingDate"
:error-messages="form().serverErrors(this, 'stopGeneratingDate')"
@input="fieldValueChanged('stopGeneratingDate')"
@@ -169,10 +169,10 @@
xl="3"
>
<v-checkbox
ref="copyWiki"
v-model="value.copyWiki"
:readonly="formState.readOnly"
:label="$ay.t('CopyWiki')"
ref="copyWiki"
data-cy="copyWiki"
:error-messages="form().serverErrors(this, 'copyWiki')"
@change="fieldValueChanged('copyWiki')"
@@ -187,10 +187,10 @@
xl="3"
>
<v-checkbox
ref="copyAttachments"
v-model="value.copyAttachments"
:readonly="formState.readOnly"
:label="$ay.t('CopyAttachments')"
ref="copyAttachments"
data-cy="copyAttachments"
:error-messages="form().serverErrors(this, 'copyAttachments')"
@change="fieldValueChanged('copyAttachments')"
@@ -199,10 +199,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="active"
v-model="value.active"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="active"
data-cy="active"
:error-messages="form().serverErrors(this, 'active')"
@change="fieldValueChanged('active')"
@@ -221,14 +221,14 @@
cols="12"
>
<v-textarea
ref="notes"
v-model="value.notes"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderSummary')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
@@ -246,12 +246,12 @@
xl="3"
>
<gz-pick-list
ref="contractId"
v-model="value.contractId"
:aya-type="$ay.ayt().Contract"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.contractId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Contract')"
ref="contractId"
data-cy="contractId"
:error-messages="form().serverErrors(this, 'contractId')"
@input="fieldValueChanged('contractId')"
@@ -272,12 +272,12 @@
xl="3"
>
<gz-pick-list
ref="projectId"
v-model="value.projectId"
:aya-type="$ay.ayt().Project"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.projectId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Project')"
ref="projectId"
data-cy="projectId"
:error-messages="form().serverErrors(this, 'projectId')"
@input="fieldValueChanged('projectId')"
@@ -292,6 +292,7 @@
xl="3"
>
<v-text-field
ref="customerContactName"
v-model="value.customerContactName"
:readonly="
formState.readOnly ||
@@ -300,7 +301,6 @@
value.userIsSubContractorRestricted
"
:label="$ay.t('WorkOrderCustomerContactName')"
ref="customerContactName"
data-cy="customerContactName"
:error-messages="form().serverErrors(this, 'customerContactName')"
@input="fieldValueChanged('customerContactName')"
@@ -321,10 +321,10 @@
xl="3"
>
<v-text-field
ref="customerReferenceNumber"
v-model="value.customerReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderCustomerReferenceNumber')"
ref="customerReferenceNumber"
data-cy="customerReferenceNumber"
:error-messages="form().serverErrors(this, 'customerReferenceNumber')"
@input="fieldValueChanged('customerReferenceNumber')"
@@ -345,10 +345,10 @@
xl="3"
>
<v-text-field
ref="internalReferenceNumber"
v-model="value.internalReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderInternalReferenceNumber')"
ref="internalReferenceNumber"
data-cy="internalReferenceNumber"
:error-messages="form().serverErrors(this, 'internalReferenceNumber')"
@input="fieldValueChanged('internalReferenceNumber')"
@@ -369,10 +369,10 @@
xl="3"
>
<v-checkbox
ref="onsite"
v-model="value.onsite"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderOnsite')"
ref="onsite"
data-cy="onsite"
:error-messages="form().serverErrors(this, 'onsite')"
@change="fieldValueChanged('onsite')"
@@ -390,9 +390,9 @@
cols="12"
>
<gz-tag-picker
ref="tags"
v-model="value.tags"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -408,12 +408,12 @@
cols="12"
>
<gz-custom-fields
ref="customFields"
v-model="value.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly || value.userIsTechRestricted"
:parent-v-m="this"
key-start-with="WorkOrderCustom"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -431,10 +431,10 @@
cols="12"
>
<gz-wiki
:aya-type="pvm.ayaType"
:aya-id="value.id"
ref="wiki"
v-model="value.wiki"
:aya-type="pvm.ayaType"
:aya-id="value.id"
:readonly="formState.readOnly || value.userIsTechRestricted"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -468,13 +468,6 @@ export default {
GzWoAddress,
GZDaysOfWeek
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
props: {
value: {
@@ -486,6 +479,21 @@ export default {
type: Object
}
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
},
methods: {
form() {
@@ -498,14 +506,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.reimburseUser`]="{ item }">
<v-simple-checkbox
@@ -86,8 +86,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -100,15 +100,15 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].name
"
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseName')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
:error-messages="
form().serverErrors(
this,
@@ -131,15 +131,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].totalCost
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTotalCost')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
data-cy="expenseTotalCost"
:error-messages="
form().serverErrors(
@@ -176,6 +176,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeAmount
@@ -183,9 +186,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeAmount')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
data-cy="expenseChargeAmount"
:error-messages="
form().serverErrors(
@@ -222,6 +222,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeToCustomer
@@ -229,9 +232,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeToCustomer')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
data-cy="chargeToCustomer"
:error-messages="
form().serverErrors(
@@ -255,15 +255,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].taxPaid
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTaxPaid')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
data-cy="expenseTaxPaid"
:error-messages="
form().serverErrors(
@@ -300,18 +300,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeTaxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
data-cy="expenseChargeTaxCode"
:error-messages="
form().serverErrors(
@@ -339,6 +339,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.reimburseUser
@@ -346,9 +349,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseReimburseUser')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
data-cy="expenseReimburseUser"
:error-messages="
form().serverErrors(
@@ -372,20 +372,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseUserID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
data-cy="expenseUser"
:error-messages="
form().serverErrors(
@@ -407,6 +407,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.description
@@ -420,16 +423,13 @@
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
data-cy="expenseDescription"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -438,15 +438,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -465,144 +456,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now()
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -784,6 +642,148 @@ export default {
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now()
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};
</script>

View File

@@ -58,10 +58,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -70,9 +70,9 @@
data-cy="laborsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -82,8 +82,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -96,16 +96,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStartDate
"
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
data-cy="serviceStartDate"
:error-messages="
form().serverErrors(
@@ -129,16 +129,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStopDate
"
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
data-cy="serviceStopDate"
:rules="[
form().datePrecedence(
@@ -169,6 +169,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateQuantity
@@ -176,9 +179,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
data-cy="laborServiceRateQuantity"
:error-messages="
form().serverErrors(
@@ -212,19 +212,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
data-cy="labors.serviceRateId"
:error-messages="
form().serverErrors(
@@ -249,20 +249,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborUserID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
data-cy="labors.userid"
:error-messages="
form().serverErrors(
@@ -287,6 +287,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.noChargeQuantity
@@ -294,9 +297,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
data-cy="laborNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -333,18 +333,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
data-cy="laborTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -372,6 +372,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.priceOverride
@@ -380,9 +383,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
data-cy="laborpriceoverride"
:error-messages="
form().serverErrors(
@@ -409,6 +409,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceDetails
@@ -422,16 +425,13 @@
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
data-cy="laborserviceDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -440,15 +440,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -467,237 +458,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -983,6 +748,241 @@ export default {
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};
</script>

View File

@@ -50,10 +50,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -62,9 +62,9 @@
data-cy="loansTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -74,8 +74,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -88,19 +88,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().LoanUnit"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
"
:aya-type="$ay.ayt().LoanUnit"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanUnit')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
data-cy="loans.loanUnitId"
:rules="[
form().required(
@@ -134,6 +134,7 @@
xl="3"
>
<v-select
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
v-model="value.items[activeWoItemIndex].loans[activeItemIndex].rate"
:items="pvm.selectLists.loanUnitRateUnits"
item-text="name"
@@ -141,7 +142,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanRate')"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
data-cy="loanUnitRateUnit"
:error-messages="
form().serverErrors(
@@ -169,15 +169,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].quantity
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanQuantity')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
data-cy="loanQuantity"
:error-messages="
form().serverErrors(
@@ -211,15 +211,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanOutDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:label="$ay.t('WorkOrderItemLoanOutDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitOutDate"
:error-messages="
form().serverErrors(
@@ -243,15 +243,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanDueDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:label="$ay.t('WorkOrderItemLoanDueDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitDueDate"
:error-messages="
form().serverErrors(
@@ -275,15 +275,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanReturnDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:label="$ay.t('WorkOrderItemLoanReturnDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitReturnDate"
:error-messages="
form().serverErrors(
@@ -310,17 +310,17 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
data-cy="loanTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -348,6 +348,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex]
.priceOverride
@@ -356,9 +359,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
data-cy="loanpriceoverride"
:error-messages="
form().serverErrors(
@@ -382,6 +382,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemLoanNotes')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].notes
"
@@ -394,14 +395,13 @@
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
data-cy="loanUnitNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -410,15 +410,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -437,151 +428,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -870,6 +721,155 @@ export default {
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="outsideServicesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,18 +87,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.unitId
"
:aya-type="$ay.ayt().Unit"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
data-cy="outsideServices.unitId"
:rules="[
form().required(
@@ -131,18 +131,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentToId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentToID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
data-cy="outsideServices.vendorSentToId"
:error-messages="
form().serverErrors(
@@ -167,6 +167,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.rmaNumber
@@ -174,9 +177,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRMANumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
:error-messages="
form().serverErrors(
this,
@@ -198,6 +198,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairCost
@@ -206,9 +209,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -238,6 +238,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairPrice
@@ -246,9 +249,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -280,18 +280,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentViaId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentViaID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
data-cy="outsideServices.vendorSentViaId"
:error-messages="
form().serverErrors(
@@ -318,6 +318,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.trackingNumber
@@ -325,9 +328,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceTrackingNumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
:error-messages="
form().serverErrors(
this,
@@ -349,6 +349,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingCost
@@ -357,9 +360,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -389,6 +389,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingPrice
@@ -397,9 +400,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -429,16 +429,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.sentDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
data-cy="outsideServiceSentDate"
:error-messages="
form().serverErrors(
@@ -462,16 +462,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.etaDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
data-cy="outsideServiceEtaDate"
:error-messages="
form().serverErrors(
@@ -495,16 +495,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.returnDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
data-cy="outsideServiceDateReturned"
:error-messages="
form().serverErrors(
@@ -528,18 +528,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('TaxCode')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
data-cy="outsideServiceTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -561,6 +561,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.notes
@@ -574,16 +577,13 @@
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
data-cy="outsideServiceNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -592,15 +592,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -619,162 +610,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1085,6 +925,166 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -66,10 +66,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -78,9 +78,9 @@
data-cy="partsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -90,8 +90,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -104,19 +104,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].partId
"
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
data-cy="parts.partId"
:error-messages="
form().serverErrors(
@@ -151,18 +151,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.partWarehouseId
"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
data-cy="parts.partWarehouseId"
:error-messages="
form().serverErrors(
@@ -186,6 +186,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].quantity
"
@@ -194,9 +197,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartQuantity')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -243,6 +243,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].suggestedQuantity`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.suggestedQuantity
@@ -252,9 +255,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartSuggestedQuantity')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].suggestedQuantity`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -284,6 +284,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].description
"
@@ -292,9 +295,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartDescription')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -321,18 +321,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.taxPartSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartTaxPartSaleID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
data-cy="partTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -360,6 +360,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.priceOverride
@@ -368,9 +371,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
data-cy="partpriceoverride"
:error-messages="
form().serverErrors(
@@ -394,6 +394,9 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemPartSerials')" cols="12">
<v-textarea
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].serials
"
@@ -406,17 +409,14 @@
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
data-cy="partSerials"
auto-grow
prepend-icon="$ayiListUl"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
auto-grow
prepend-icon="$ayiListUl"
@click:prepend="selectSerials()"
></v-textarea>
</v-col>
@@ -427,16 +427,16 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="partAssemblyDialog">
<v-dialog v-model="partAssemblyDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedPartAssembly"
v-model="selectedPartAssembly"
:aya-type="$ay.ayt().PartAssembly"
show-edit-icon
v-model="selectedPartAssembly"
:label="$ay.t('PartAssemblyList')"
ref="selectedPartAssembly"
data-cy="selectedPartAssembly"
></gz-pick-list>
@@ -445,16 +445,16 @@
pvm.useInventory &&
form().showMe(this, 'WorkOrderItemPartPartWarehouseID')
"
ref="selectedPartWarehouse"
v-model="selectedPartWarehouse"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
v-model="selectedPartWarehouse"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
ref="selectedPartWarehouse"
data-cy="selectedPartWarehouse"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="partAssemblyDialog = false" color="primary">{{
<v-btn text color="primary" @click="partAssemblyDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -462,8 +462,8 @@
:disabled="selectedPartAssembly == null"
color="primary"
text
@click="addPartAssembly()"
class="ml-4"
@click="addPartAssembly()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -476,10 +476,10 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="serialDialog">
<v-dialog v-model="serialDialog" persistent max-width="600px">
<v-card>
<v-card-title>
<v-btn text @click="serialDialog = false" color="primary">{{
<v-btn text color="primary" @click="serialDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -507,21 +507,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
props: {
value: {
default: null,
@@ -540,6 +525,320 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSuggestedQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartSuggestedQuantity"),
align: "right",
value: "suggestedQuantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
suggestedQuantity: window.$gz.locale.decimalLocalized(
x.suggestedQuantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -564,6 +863,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
generateUnit() {
const thisPart = this.value.items[this.activeWoItemIndex].parts[
@@ -871,308 +1173,6 @@ export default {
return ret;
}
//---
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSuggestedQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartSuggestedQuantity"),
align: "right",
value: "suggestedQuantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
suggestedQuantity: window.$gz.locale.decimalLocalized(
x.suggestedQuantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
}
};
</script>

View File

@@ -71,10 +71,10 @@
<!-- ################################ SCHEDULED USERS TABLE ############################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -83,9 +83,9 @@
data-cy="scheduledUsersTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -95,8 +95,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -109,16 +109,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.startDate
"
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
data-cy="startDate"
:error-messages="
form().serverErrors(
@@ -142,16 +142,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.stopDate
"
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
data-cy="stopDate"
:rules="[
form().datePrecedence(
@@ -184,6 +184,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.estimatedQuantity
@@ -193,9 +196,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserEstimatedQuantity')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
data-cy="scheduledUsers.EstimatedQuantity"
:error-messages="
form().serverErrors(
@@ -229,21 +229,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserUserID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
data-cy="scheduledUsers.userid"
:error-messages="
form().serverErrors(
@@ -268,21 +268,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
data-cy="scheduledUsers.serviceRateId"
:error-messages="
form().serverErrors(
@@ -304,15 +304,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -331,6 +322,136 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -355,6 +476,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
convertAllToLabor() {
this.value.items[this.activeWoItemIndex].scheduledUsers.forEach(z => {
@@ -574,130 +698,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
}
};
</script>

View File

@@ -55,10 +55,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -67,9 +67,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -79,8 +79,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -93,15 +93,15 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].sequence
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:label="$ay.t('Sequence')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
:rules="[
form().integerValid(
this,
@@ -114,12 +114,12 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
></v-text-field>
</v-col>
@@ -136,6 +136,9 @@
xl="3"
>
<v-select
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].status
"
@@ -145,9 +148,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskWorkOrderItemTaskCompletionType')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
data-cy="usertype"
:rules="[
form().integerValid(
@@ -178,21 +178,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedByUserId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskUser')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
data-cy="expenseUser"
:error-messages="
form().serverErrors(
@@ -217,16 +217,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedDate
"
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
data-cy="travelCompletedDate"
:error-messages="
form().serverErrors(
@@ -244,6 +244,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemTaskTaskID')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
v-model="value.items[activeWoItemIndex].tasks[activeItemIndex].task"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -260,14 +261,13 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
]"
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
data-cy="task"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -277,21 +277,21 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="taskGroupDialog">
<v-dialog v-model="taskGroupDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedTaskGroup"
v-model="selectedTaskGroup"
:aya-type="$ay.ayt().TaskGroup"
show-edit-icon
v-model="selectedTaskGroup"
:label="$ay.t('TaskGroupList')"
ref="selectedTaskGroup"
data-cy="selectedTaskGroup"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="taskGroupDialog = false" color="primary">{{
<v-btn text color="primary" @click="taskGroupDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -299,8 +299,8 @@
:disabled="selectedTaskGroup == null"
color="primary"
text
@click="addTaskGroup()"
class="ml-4"
@click="addTaskGroup()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -312,17 +312,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
props: {
value: {
default: null,
@@ -341,6 +330,127 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -365,6 +475,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
async addTaskGroup() {
const res = await window.$gz.api.get(
@@ -533,119 +646,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="travelsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,16 +87,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStartDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStartDate
"
:label="$ay.t('WorkOrderItemTravelStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
data-cy="travelStartDate"
:error-messages="
form().serverErrors(
@@ -120,16 +120,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStopDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStopDate
"
:label="$ay.t('WorkOrderItemTravelStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
data-cy="travelStopDate"
:rules="[
form().datePrecedence(
@@ -160,6 +160,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateQuantity
@@ -167,9 +170,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
data-cy="travelTravelRateQuantity"
:error-messages="
form().serverErrors(
@@ -202,15 +202,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].distance
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelDistance')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
data-cy="travelTravelRateDistance"
:error-messages="
form().serverErrors(
@@ -243,19 +243,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateId
"
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
data-cy="travels.travelRateId"
:error-messages="
form().serverErrors(
@@ -280,20 +280,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelUserID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
data-cy="travels.userid"
:error-messages="
form().serverErrors(
@@ -318,6 +318,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.noChargeQuantity
@@ -325,9 +328,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
data-cy="travelNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -364,18 +364,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
data-cy="travelTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -403,6 +403,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.priceOverride
@@ -411,9 +414,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
data-cy="travelpriceoverride"
:error-messages="
form().serverErrors(
@@ -440,6 +440,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelDetails
@@ -453,16 +456,13 @@
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
data-cy="traveltravelDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -471,15 +471,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -498,225 +489,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId: null,
price: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1015,6 +792,229 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId: null,
price: 0,
priceOverride: null,
isDirty: true,
pmItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -57,10 +57,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -69,9 +69,9 @@
data-cy="unitsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -81,8 +81,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -94,20 +94,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].unitId
"
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
data-cy="units.unitId"
:rules="[
form().required(
@@ -166,6 +166,7 @@
cols="12"
>
<v-textarea
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].notes
"
@@ -178,14 +179,13 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
data-cy="unitUnitNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
@@ -197,6 +197,7 @@
cols="12"
>
<gz-tag-picker
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].tags"
:readonly="formState.readOnly"
data-cy="unitTags"
@@ -206,7 +207,6 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
@@ -217,6 +217,9 @@
<v-col v-if="!value.userIsRestrictedType" cols="12">
<gz-custom-fields
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].customFields
"
@@ -224,9 +227,6 @@
:readonly="formState.readOnly"
:parent-v-m="this"
key-start-with="WorkOrderItemUnitCustom"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
data-cy="unitCustomFields"
:error-messages="
form().serverErrors(
@@ -250,10 +250,10 @@
cols="12"
>
<gz-wiki
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].wiki`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].wiki"
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:readonly="formState.readOnly"
@input="
fieldValueChanged(
@@ -284,22 +284,22 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="bulkUnitsDialog">
<v-dialog v-model="bulkUnitsDialog" persistent max-width="600px">
<v-card>
<v-card-title>{{ $ay.t("AddMultipleUnits") }}</v-card-title>
<v-card-text>
<gz-tag-picker v-model="selectedBulkUnitTags"></gz-tag-picker>
<gz-pick-list
v-model="selectedBulkUnitCustomer"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="false"
v-model="selectedBulkUnitCustomer"
:label="$ay.t('Customer')"
:can-clear="true"
></gz-pick-list>
<v-data-table
dense
v-model="selectedBulkUnits"
dense
:headers="bulkUnitTableHeaders"
:items="availableBulkUnits"
class="my-10"
@@ -312,7 +312,7 @@
</v-data-table>
</v-card-text>
<v-card-actions>
<v-btn text @click="bulkUnitsDialog = false" color="primary">{{
<v-btn text color="primary" @click="bulkUnitsDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -339,21 +339,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
props: {
value: {
default: null,
@@ -376,6 +361,126 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -400,6 +505,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
async updateContractIfApplicable() {
const id = this.value.items[this.activeWoItemIndex].units[
@@ -688,114 +796,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

View File

@@ -163,10 +163,10 @@
<!-- ################################ WORK ORDER ITEMS TABLE ############################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -175,9 +175,9 @@
data-cy="itemsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.status`]="{ item }">
<template v-if="item.status.id != null">
@@ -208,8 +208,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -219,6 +219,7 @@
cols="12"
>
<v-textarea
:ref="`items[${activeItemIndex}].notes`"
v-model="value.items[activeItemIndex].notes"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -226,11 +227,10 @@
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].notes`)
"
:ref="`items[${activeItemIndex}].notes`"
:rules="[form().required(this, `items[${activeItemIndex}].notes`)]"
data-cy="Items.Notes"
@input="fieldValueChanged(`items[${activeItemIndex}].notes`)"
auto-grow
@input="fieldValueChanged(`items[${activeItemIndex}].notes`)"
></v-textarea>
</v-col>
@@ -245,24 +245,25 @@
xl="3"
>
<v-text-field
:ref="`items[${activeItemIndex}].sequence`"
v-model="value.items[activeItemIndex].sequence"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:label="$ay.t('Sequence')"
:ref="`items[${activeItemIndex}].sequence`"
:rules="[
form().integerValid(this, `items[${activeItemIndex}].sequence`)
]"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].sequence`)
"
@input="fieldValueChanged(`items[${activeItemIndex}].sequence`)"
type="number"
@input="fieldValueChanged(`items[${activeItemIndex}].sequence`)"
></v-text-field>
</v-col>
<v-col v-if="form().showMe(this, 'WorkOrderItemTechNotes')" cols="12">
<v-textarea
:ref="`items[${activeItemIndex}].techNotes`"
v-model="value.items[activeItemIndex].techNotes"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -270,10 +271,9 @@
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].techNotes`)
"
:ref="`items[${activeItemIndex}].techNotes`"
data-cy="items.techNotes"
@input="fieldValueChanged(`items[${activeItemIndex}].techNotes`)"
auto-grow
@input="fieldValueChanged(`items[${activeItemIndex}].techNotes`)"
></v-textarea>
</v-col>
@@ -288,11 +288,11 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemRequestDate')"
:ref="`items[${activeItemIndex}].requestDate`"
v-model="value.items[activeItemIndex].requestDate"
:label="$ay.t('WorkOrderItemRequestDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="`items[${activeItemIndex}].requestDate`"
data-cy="requestDate"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].requestDate`)
@@ -312,10 +312,10 @@
xl="3"
>
<v-autocomplete
:ref="`items[${activeItemIndex}].workOrderItemStatusId`"
v-model="value.items[activeItemIndex].workOrderItemStatusId"
:readonly="formState.readOnly"
:disabled="isDeleted"
@input="fieldValueChanged('workOrderItemStatusId')"
:items="selectableStatusList"
item-text="name"
item-value="id"
@@ -326,9 +326,9 @@
`items[${activeItemIndex}].workOrderItemStatusId`
)
"
:ref="`items[${activeItemIndex}].workOrderItemStatusId`"
data-cy="workOrderItemStatusId"
prepend-icon="$ayiEdit"
@input="fieldValueChanged('workOrderItemStatusId')"
@click:prepend="handleEditItemStatusClick()"
>
<template v-slot:selection="{ item }">
@@ -368,10 +368,10 @@
xl="3"
>
<v-autocomplete
:ref="`items[${activeItemIndex}].workOrderItemPriorityId`"
v-model="value.items[activeItemIndex].workOrderItemPriorityId"
:readonly="formState.readOnly"
:disabled="isDeleted"
@input="fieldValueChanged('workOrderItemPriorityId')"
:items="selectablePriorityList"
item-text="name"
item-value="id"
@@ -382,9 +382,9 @@
`items[${activeItemIndex}].workOrderItemPriorityId`
)
"
:ref="`items[${activeItemIndex}].workOrderItemPriorityId`"
data-cy="workOrderItemPriorityId"
prepend-icon="$ayiEdit"
@input="fieldValueChanged('workOrderItemPriorityId')"
@click:prepend="handleEditItemPriorityClick()"
>
<template v-slot:selection="{ item }">
@@ -423,11 +423,11 @@
xl="3"
>
<v-checkbox
:ref="`items[${activeItemIndex}].warrantyService`"
v-model="value.items[activeItemIndex].warrantyService"
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemWarrantyService')"
:ref="`items[${activeItemIndex}].warrantyService`"
data-cy="warrantyService"
:error-messages="
form().serverErrors(
@@ -447,9 +447,9 @@
cols="12"
>
<gz-tag-picker
:ref="`items[${activeItemIndex}].tags`"
v-model="value.items[activeItemIndex].tags"
:readonly="formState.readOnly"
:ref="`items[${activeItemIndex}].tags`"
data-cy="tags"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].tags`)
@@ -460,12 +460,12 @@
<v-col v-if="!value.userIsRestrictedType" cols="12">
<gz-custom-fields
:ref="`items[${activeItemIndex}].customFields`"
v-model="value.items[activeItemIndex].customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly"
:parent-v-m="this"
key-start-with="WorkOrderItemCustom"
:ref="`items[${activeItemIndex}].customFields`"
data-cy="customFields"
:error-messages="
form().serverErrors(
@@ -485,10 +485,10 @@
cols="12"
>
<gz-wiki
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:ref="`items[${activeItemIndex}].wiki`"
v-model="value.items[activeItemIndex].wiki"
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -513,7 +513,7 @@
GRANDCHILDREN
############################################################################ -->
<v-col cols="12" v-show="showUnits">
<v-col v-show="showUnits" cols="12">
<GzPMItemUnits
v-model="value"
:pvm="pvm"
@@ -524,7 +524,7 @@
/>
</v-col>
<v-col cols="12" v-show="showScheduledUsers">
<v-col v-show="showScheduledUsers" cols="12">
<GzPMItemScheduledUsers
v-model="value"
:pvm="pvm"
@@ -534,7 +534,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showTasks">
<v-col v-show="showTasks" cols="12">
<GzPMItemTasks
v-model="value"
:pvm="pvm"
@@ -545,7 +545,7 @@
/>
</v-col>
<v-col cols="12" v-show="showParts">
<v-col v-show="showParts" cols="12">
<GzPMItemParts
v-model="value"
:pvm="pvm"
@@ -556,7 +556,7 @@
/>
</v-col>
<v-col cols="12" v-show="showLabors">
<v-col v-show="showLabors" cols="12">
<GzPMItemLabors
v-model="value"
:pvm="pvm"
@@ -566,7 +566,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showTravels">
<v-col v-show="showTravels" cols="12">
<GzPMItemTravels
v-model="value"
:pvm="pvm"
@@ -576,7 +576,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showExpenses">
<v-col v-show="showExpenses" cols="12">
<GzPMItemExpenses
v-model="value"
:pvm="pvm"
@@ -587,7 +587,7 @@
/>
</v-col>
<v-col cols="12" v-show="showLoans">
<v-col v-show="showLoans" cols="12">
<GzPMItemLoans
v-model="value"
:pvm="pvm"
@@ -597,7 +597,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showOutsideServices">
<v-col v-show="showOutsideServices" cols="12">
<GzPMItemOutsideServices
v-model="value"
:pvm="pvm"
@@ -634,8 +634,19 @@ export default {
GzPMItemLoans,
GzPMItemOutsideServices
},
created() {
this.setDefaultView();
props: {
value: {
default: null,
type: Object
},
pvm: {
default: null,
type: Object
},
goto: {
default: null,
type: Object
}
},
data() {
return {
@@ -652,308 +663,6 @@ export default {
gotoUnitIndex: null
};
},
props: {
value: {
default: null,
type: Object
},
pvm: {
default: null,
type: Object
},
goto: {
default: null,
type: Object
}
},
watch: {
goto(val, oldVal) {
if (val != oldVal) {
const navto = { woitemindex: null, childindex: null };
//find the item in question then trigger the nav
let keepgoing = true;
this.value.items.forEach((z, itemindex) => {
if (keepgoing) {
switch (val.type) {
case window.$gz.type.PMItem:
if (z.id == val.id) {
navto.woitemindex = itemindex;
keepgoing = false;
}
break;
case window.$gz.type.PMItemOutsideService:
z.outsideServices.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemExpense:
z.expenses.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemLabor:
z.labors.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemLoan:
z.loans.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemPart:
z.parts.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemScheduledUser:
z.scheduledUsers.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemTask:
z.tasks.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemTravel:
z.travels.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemUnit:
z.units.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
}
}
});
if (navto.woitemindex != null) {
this.selectedRow = [{ index: navto.woitemindex }];
this.activeItemIndex = navto.woitemindex;
this.$nextTick(() => {
const el = this.$refs.topform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
if (navto.childindex != null) {
this.$nextTick(() => {
switch (val.type) {
case window.$gz.type.PMItemOutsideService:
this.gotoOutsideServiceIndex = navto.childindex;
break;
case window.$gz.type.PMItemExpense:
this.gotoExpenseIndex = navto.childindex;
break;
case window.$gz.type.PMItemLabor:
this.gotoLaborIndex = navto.childindex;
break;
case window.$gz.type.PMItemLoan:
this.gotoLoanIndex = navto.childindex;
break;
case window.$gz.type.PMItemPart:
this.gotoPartIndex = navto.childindex;
break;
case window.$gz.type.PMItemTask:
this.gotoTaskIndex = navto.childindex;
break;
case window.$gz.type.PMItemScheduledUser:
this.gotoScheduledUserIndex = navto.childindex;
break;
case window.$gz.type.PMItemTravel:
this.gotoTravelIndex = navto.childindex;
break;
case window.$gz.type.PMItemUnit:
this.gotoUnitIndex = navto.childindex;
break;
}
});
}
}
}
}
},
methods: {
newItem() {
const newIndex = this.value.items.length;
this.value.items.push({
id: 0,
concurrency: 0,
notes: undefined, //to trigger validation on new
wiki: null,
customFields: "{}",
tags: [],
pmId: this.value.id,
techNotes: null,
workOrderItemStatusId: null,
workOrderItemPriorityId: null,
requestDate: null,
warrantyService: false,
sequence: newIndex + 1, //indexes are zero based but sequences are visible to user so 1 based
isDirty: true,
expenses: [],
labors: [],
loans: [],
parts: [],
scheduledUsers: [],
tasks: [],
travels: [],
units: [],
outsideServices: [],
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeItemIndex].notes = null;
this.fieldValueChanged(`items[${this.activeItemIndex}].notes`);
});
},
newSubItem(atype) {
//new Id value to use (by convention goto negative will trigger create and then goto instead of simple goto)
const newId = -Math.abs(Date.now());
switch (atype) {
case window.$gz.type.WorkOrderItemOutsideService:
this.gotoOutsideServiceIndex = newId;
break;
case window.$gz.type.WorkOrderItemExpense:
this.gotoExpenseIndex = newId;
break;
case window.$gz.type.WorkOrderItemLabor:
this.gotoLaborIndex = newId;
break;
case window.$gz.type.WorkOrderItemLoan:
this.gotoLoanIndex = newId;
break;
case window.$gz.type.WorkOrderItemPart:
this.gotoPartIndex = newId;
break;
case window.$gz.type.WorkOrderItemTask:
this.gotoTaskIndex = newId;
break;
case window.$gz.type.WorkOrderItemScheduledUser:
this.gotoScheduledUserIndex = newId;
break;
case window.$gz.type.WorkOrderItemTravel:
this.gotoTravelIndex = newId;
break;
case window.$gz.type.WorkOrderItemUnit:
this.gotoUnitIndex = newId;
break;
}
},
unDeleteItem() {
this.value.items[this.activeItemIndex].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeItemIndex].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items.forEach(z => (z.deleted = true));
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value && this.value.items && this.value.items.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
handleEditItemStatusClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemStatus,
id: this.value.items[this.activeItemIndex].workOrderItemStatusId
});
},
handleEditItemPriorityClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemPriority,
id: this.value.items[this.activeItemIndex].workOrderItemPriorityId
});
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeItemIndex].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted = this.value.items[item.index].deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
},
computed: {
isDeleted: function() {
if (this.value.items[this.activeItemIndex] == null) {
@@ -1217,6 +926,297 @@ export default {
!this.value.userIsRestrictedType
);
}
},
watch: {
goto(val, oldVal) {
if (val != oldVal) {
const navto = { woitemindex: null, childindex: null };
//find the item in question then trigger the nav
let keepgoing = true;
this.value.items.forEach((z, itemindex) => {
if (keepgoing) {
switch (val.type) {
case window.$gz.type.PMItem:
if (z.id == val.id) {
navto.woitemindex = itemindex;
keepgoing = false;
}
break;
case window.$gz.type.PMItemOutsideService:
z.outsideServices.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemExpense:
z.expenses.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemLabor:
z.labors.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemLoan:
z.loans.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemPart:
z.parts.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemScheduledUser:
z.scheduledUsers.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemTask:
z.tasks.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemTravel:
z.travels.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.PMItemUnit:
z.units.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
}
}
});
if (navto.woitemindex != null) {
this.selectedRow = [{ index: navto.woitemindex }];
this.activeItemIndex = navto.woitemindex;
this.$nextTick(() => {
const el = this.$refs.topform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
if (navto.childindex != null) {
this.$nextTick(() => {
switch (val.type) {
case window.$gz.type.PMItemOutsideService:
this.gotoOutsideServiceIndex = navto.childindex;
break;
case window.$gz.type.PMItemExpense:
this.gotoExpenseIndex = navto.childindex;
break;
case window.$gz.type.PMItemLabor:
this.gotoLaborIndex = navto.childindex;
break;
case window.$gz.type.PMItemLoan:
this.gotoLoanIndex = navto.childindex;
break;
case window.$gz.type.PMItemPart:
this.gotoPartIndex = navto.childindex;
break;
case window.$gz.type.PMItemTask:
this.gotoTaskIndex = navto.childindex;
break;
case window.$gz.type.PMItemScheduledUser:
this.gotoScheduledUserIndex = navto.childindex;
break;
case window.$gz.type.PMItemTravel:
this.gotoTravelIndex = navto.childindex;
break;
case window.$gz.type.PMItemUnit:
this.gotoUnitIndex = navto.childindex;
break;
}
});
}
}
}
}
},
created() {
this.setDefaultView();
},
methods: {
newItem() {
const newIndex = this.value.items.length;
this.value.items.push({
id: 0,
concurrency: 0,
notes: undefined, //to trigger validation on new
wiki: null,
customFields: "{}",
tags: [],
pmId: this.value.id,
techNotes: null,
workOrderItemStatusId: null,
workOrderItemPriorityId: null,
requestDate: null,
warrantyService: false,
sequence: newIndex + 1, //indexes are zero based but sequences are visible to user so 1 based
isDirty: true,
expenses: [],
labors: [],
loans: [],
parts: [],
scheduledUsers: [],
tasks: [],
travels: [],
units: [],
outsideServices: [],
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeItemIndex].notes = null;
this.fieldValueChanged(`items[${this.activeItemIndex}].notes`);
});
},
newSubItem(atype) {
//new Id value to use (by convention goto negative will trigger create and then goto instead of simple goto)
const newId = -Math.abs(Date.now());
switch (atype) {
case window.$gz.type.WorkOrderItemOutsideService:
this.gotoOutsideServiceIndex = newId;
break;
case window.$gz.type.WorkOrderItemExpense:
this.gotoExpenseIndex = newId;
break;
case window.$gz.type.WorkOrderItemLabor:
this.gotoLaborIndex = newId;
break;
case window.$gz.type.WorkOrderItemLoan:
this.gotoLoanIndex = newId;
break;
case window.$gz.type.WorkOrderItemPart:
this.gotoPartIndex = newId;
break;
case window.$gz.type.WorkOrderItemTask:
this.gotoTaskIndex = newId;
break;
case window.$gz.type.WorkOrderItemScheduledUser:
this.gotoScheduledUserIndex = newId;
break;
case window.$gz.type.WorkOrderItemTravel:
this.gotoTravelIndex = newId;
break;
case window.$gz.type.WorkOrderItemUnit:
this.gotoUnitIndex = newId;
break;
}
},
unDeleteItem() {
this.value.items[this.activeItemIndex].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeItemIndex].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items.forEach(z => (z.deleted = true));
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value && this.value.items && this.value.items.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
handleEditItemStatusClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemStatus,
id: this.value.items[this.activeItemIndex].workOrderItemStatusId
});
},
handleEditItemPriorityClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemPriority,
id: this.value.items[this.activeItemIndex].workOrderItemPriorityId
});
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeItemIndex].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted = this.value.items[item.index].deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};

View File

@@ -2,17 +2,17 @@
<div>
<v-row>
<v-col
v-if="value.serial != 0 && canEditSerial"
cols="12"
sm="6"
lg="4"
xl="3"
v-if="value.serial != 0 && canEditSerial"
>
<v-text-field
ref="serial"
v-model="value.serial"
:readonly="formState.readOnly"
:label="$ay.t('QuoteSerialNumber')"
ref="serial"
data-cy="serial"
:rules="[
form().integerValid(this, 'serial'),
@@ -24,13 +24,13 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="customerId"
v-model="value.customerId"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.customerId"
:readonly="formState.readOnly || value.userIsRestrictedType"
:label="$ay.t('Customer')"
:can-clear="false"
ref="customerId"
data-cy="customerId"
:rules="[form().required(this, 'customerId')]"
:error-messages="form().serverErrors(this, 'customerId')"
@@ -52,12 +52,12 @@
xl="3"
>
<gz-pick-list
ref="preparedById"
v-model="value.preparedById"
:aya-type="$ay.ayt().User"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.preparedById"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('QuotePreparedByID')"
ref="preparedById"
data-cy="preparedById"
:error-messages="form().serverErrors(this, 'preparedById')"
@input="fieldValueChanged('preparedById')"
@@ -116,14 +116,14 @@
cols="12"
>
<v-textarea
ref="introduction"
v-model="value.introduction"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('QuoteIntroduction')"
:error-messages="form().serverErrors(this, 'introduction')"
ref="introduction"
data-cy="introduction"
@input="fieldValueChanged('introduction')"
auto-grow
@input="fieldValueChanged('introduction')"
></v-textarea>
</v-col>
<v-col
@@ -137,14 +137,14 @@
cols="12"
>
<v-textarea
ref="notes"
v-model="value.notes"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderSummary')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
@@ -162,10 +162,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('QuoteQuoteRequestDate')"
v-model="value.requested"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="requested"
v-model="value.requested"
:label="$ay.t('QuoteQuoteRequestDate')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="requested"
:error-messages="form().serverErrors(this, 'requested')"
@input="fieldValueChanged('requested')"
@@ -186,10 +186,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('QuoteValidUntilDate')"
v-model="value.validUntil"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="validUntil"
v-model="value.validUntil"
:label="$ay.t('QuoteValidUntilDate')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="validUntil"
:error-messages="form().serverErrors(this, 'validUntil')"
@input="fieldValueChanged('validUntil')"
@@ -210,10 +210,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('QuoteDateSubmitted')"
v-model="value.submitted"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="submitted"
v-model="value.submitted"
:label="$ay.t('QuoteDateSubmitted')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="submitted"
:error-messages="form().serverErrors(this, 'submitted')"
@input="fieldValueChanged('submitted')"
@@ -234,10 +234,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('QuoteDateApproved')"
v-model="value.approved"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="approved"
v-model="value.approved"
:label="$ay.t('QuoteDateApproved')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="approved"
:error-messages="form().serverErrors(this, 'approved')"
@input="fieldValueChanged('approved')"
@@ -258,12 +258,12 @@
xl="3"
>
<gz-pick-list
ref="contractId"
v-model="value.contractId"
:aya-type="$ay.ayt().Contract"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.contractId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Contract')"
ref="contractId"
data-cy="contractId"
:error-messages="form().serverErrors(this, 'contractId')"
@input="fieldValueChanged('contractId')"
@@ -284,12 +284,12 @@
xl="3"
>
<gz-pick-list
ref="projectId"
v-model="value.projectId"
:aya-type="$ay.ayt().Project"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.projectId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Project')"
ref="projectId"
data-cy="projectId"
:error-messages="form().serverErrors(this, 'projectId')"
@input="fieldValueChanged('projectId')"
@@ -304,6 +304,7 @@
xl="3"
>
<v-text-field
ref="customerContactName"
v-model="value.customerContactName"
:readonly="
formState.readOnly ||
@@ -312,7 +313,6 @@
value.userIsSubContractorRestricted
"
:label="$ay.t('WorkOrderCustomerContactName')"
ref="customerContactName"
data-cy="customerContactName"
:error-messages="form().serverErrors(this, 'customerContactName')"
@input="fieldValueChanged('customerContactName')"
@@ -333,10 +333,10 @@
xl="3"
>
<v-text-field
ref="customerReferenceNumber"
v-model="value.customerReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderCustomerReferenceNumber')"
ref="customerReferenceNumber"
data-cy="customerReferenceNumber"
:error-messages="form().serverErrors(this, 'customerReferenceNumber')"
@input="fieldValueChanged('customerReferenceNumber')"
@@ -357,10 +357,10 @@
xl="3"
>
<v-text-field
ref="internalReferenceNumber"
v-model="value.internalReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderInternalReferenceNumber')"
ref="internalReferenceNumber"
data-cy="internalReferenceNumber"
:error-messages="form().serverErrors(this, 'internalReferenceNumber')"
@input="fieldValueChanged('internalReferenceNumber')"
@@ -381,10 +381,10 @@
xl="3"
>
<v-checkbox
ref="onsite"
v-model="value.onsite"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderOnsite')"
ref="onsite"
data-cy="onsite"
:error-messages="form().serverErrors(this, 'onsite')"
@change="fieldValueChanged('onsite')"
@@ -402,9 +402,9 @@
cols="12"
>
<gz-tag-picker
ref="tags"
v-model="value.tags"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -420,12 +420,12 @@
cols="12"
>
<gz-custom-fields
ref="customFields"
v-model="value.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly || value.userIsTechRestricted"
:parent-v-m="this"
key-start-with="WorkOrderCustom"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -443,10 +443,10 @@
cols="12"
>
<gz-wiki
:aya-type="pvm.ayaType"
:aya-id="value.id"
ref="wiki"
v-model="value.wiki"
:aya-type="pvm.ayaType"
:aya-id="value.id"
:readonly="formState.readOnly || value.userIsTechRestricted"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -480,13 +480,6 @@ export default {
GzQuoteState,
GzWoAddress
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
props: {
value: {
@@ -498,6 +491,21 @@ export default {
type: Object
}
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
},
methods: {
form() {
@@ -510,14 +518,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.reimburseUser`]="{ item }">
<v-simple-checkbox
@@ -86,8 +86,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -100,15 +100,15 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].name
"
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseName')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
:error-messages="
form().serverErrors(
this,
@@ -131,15 +131,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].totalCost
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTotalCost')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
data-cy="expenseTotalCost"
:error-messages="
form().serverErrors(
@@ -176,6 +176,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeAmount
@@ -183,9 +186,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeAmount')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
data-cy="expenseChargeAmount"
:error-messages="
form().serverErrors(
@@ -222,6 +222,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeToCustomer
@@ -229,9 +232,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeToCustomer')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
data-cy="chargeToCustomer"
:error-messages="
form().serverErrors(
@@ -255,15 +255,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].taxPaid
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTaxPaid')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
data-cy="expenseTaxPaid"
:error-messages="
form().serverErrors(
@@ -300,18 +300,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeTaxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
data-cy="expenseChargeTaxCode"
:error-messages="
form().serverErrors(
@@ -339,6 +339,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.reimburseUser
@@ -346,9 +349,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseReimburseUser')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
data-cy="expenseReimburseUser"
:error-messages="
form().serverErrors(
@@ -372,20 +372,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseUserID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
data-cy="expenseUser"
:error-messages="
form().serverErrors(
@@ -407,6 +407,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.description
@@ -420,16 +423,13 @@
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
data-cy="expenseDescription"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -438,15 +438,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -465,144 +456,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -780,6 +638,148 @@ export default {
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};
</script>

View File

@@ -58,10 +58,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -70,9 +70,9 @@
data-cy="laborsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -82,8 +82,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -96,16 +96,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStartDate
"
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
data-cy="serviceStartDate"
:error-messages="
form().serverErrors(
@@ -129,16 +129,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStopDate
"
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
data-cy="serviceStopDate"
:rules="[
form().datePrecedence(
@@ -169,6 +169,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateQuantity
@@ -176,9 +179,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
data-cy="laborServiceRateQuantity"
:error-messages="
form().serverErrors(
@@ -212,19 +212,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
data-cy="labors.serviceRateId"
:error-messages="
form().serverErrors(
@@ -249,20 +249,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborUserID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
data-cy="labors.userid"
:error-messages="
form().serverErrors(
@@ -287,6 +287,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.noChargeQuantity
@@ -294,9 +297,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
data-cy="laborNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -333,18 +333,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
data-cy="laborTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -372,6 +372,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.priceOverride
@@ -380,9 +383,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
data-cy="laborpriceoverride"
:error-messages="
form().serverErrors(
@@ -409,6 +409,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceDetails
@@ -422,16 +425,13 @@
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
data-cy="laborserviceDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -440,15 +440,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -467,238 +458,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -985,6 +749,242 @@ export default {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -50,10 +50,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -62,9 +62,9 @@
data-cy="loansTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -74,8 +74,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -88,19 +88,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().LoanUnit"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
"
:aya-type="$ay.ayt().LoanUnit"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanUnit')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
data-cy="loans.loanUnitId"
:rules="[
form().required(
@@ -134,6 +134,7 @@
xl="3"
>
<v-select
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
v-model="value.items[activeWoItemIndex].loans[activeItemIndex].rate"
:items="pvm.selectLists.loanUnitRateUnits"
item-text="name"
@@ -141,7 +142,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanRate')"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
data-cy="loanUnitRateUnit"
:error-messages="
form().serverErrors(
@@ -169,15 +169,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].quantity
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanQuantity')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
data-cy="loanQuantity"
:error-messages="
form().serverErrors(
@@ -211,15 +211,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanOutDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:label="$ay.t('WorkOrderItemLoanOutDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitOutDate"
:error-messages="
form().serverErrors(
@@ -243,15 +243,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanDueDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:label="$ay.t('WorkOrderItemLoanDueDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitDueDate"
:error-messages="
form().serverErrors(
@@ -275,15 +275,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanReturnDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:label="$ay.t('WorkOrderItemLoanReturnDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loanUnitReturnDate"
:error-messages="
form().serverErrors(
@@ -310,17 +310,17 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
data-cy="loanTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -348,6 +348,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex]
.priceOverride
@@ -356,9 +359,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
data-cy="loanpriceoverride"
:error-messages="
form().serverErrors(
@@ -382,6 +382,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemLoanNotes')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].notes
"
@@ -394,14 +395,13 @@
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
data-cy="loanUnitNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -410,15 +410,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -437,151 +428,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -872,6 +723,155 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="outsideServicesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,18 +87,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.unitId
"
:aya-type="$ay.ayt().Unit"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
data-cy="outsideServices.unitId"
:rules="[
form().required(
@@ -131,18 +131,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentToId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentToID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
data-cy="outsideServices.vendorSentToId"
:error-messages="
form().serverErrors(
@@ -167,6 +167,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.rmaNumber
@@ -174,9 +177,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRMANumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
:error-messages="
form().serverErrors(
this,
@@ -198,6 +198,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairCost
@@ -206,9 +209,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -238,6 +238,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairPrice
@@ -246,9 +249,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -280,18 +280,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentViaId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentViaID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
data-cy="outsideServices.vendorSentViaId"
:error-messages="
form().serverErrors(
@@ -318,6 +318,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.trackingNumber
@@ -325,9 +328,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceTrackingNumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
:error-messages="
form().serverErrors(
this,
@@ -349,6 +349,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingCost
@@ -357,9 +360,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -389,6 +389,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingPrice
@@ -397,9 +400,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
data-cy="outsideServicepriceoverride"
:error-messages="
form().serverErrors(
@@ -429,16 +429,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.sentDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
data-cy="outsideServiceSentDate"
:error-messages="
form().serverErrors(
@@ -462,16 +462,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.etaDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
data-cy="outsideServiceEtaDate"
:error-messages="
form().serverErrors(
@@ -495,16 +495,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.returnDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
data-cy="outsideServiceDateReturned"
:error-messages="
form().serverErrors(
@@ -528,18 +528,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('TaxCode')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
data-cy="outsideServiceTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -561,6 +561,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.notes
@@ -574,16 +577,13 @@
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
data-cy="outsideServiceNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -592,15 +592,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -619,162 +610,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1085,6 +925,166 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -66,10 +66,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -78,9 +78,9 @@
data-cy="partsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -90,8 +90,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -104,19 +104,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].partId
"
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
data-cy="parts.partId"
:error-messages="
form().serverErrors(
@@ -151,18 +151,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.partWarehouseId
"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
data-cy="parts.partWarehouseId"
:error-messages="
form().serverErrors(
@@ -186,6 +186,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].quantity
"
@@ -194,9 +197,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartQuantity')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -243,6 +243,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].description
"
@@ -251,9 +254,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartDescription')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -280,18 +280,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.taxPartSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartTaxPartSaleID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
data-cy="partTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -319,6 +319,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.priceOverride
@@ -327,9 +330,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
data-cy="partpriceoverride"
:error-messages="
form().serverErrors(
@@ -353,6 +353,9 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemPartSerials')" cols="12">
<v-textarea
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].serials
"
@@ -365,17 +368,14 @@
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
data-cy="partSerials"
auto-grow
prepend-icon="$ayiListUl"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
auto-grow
prepend-icon="$ayiListUl"
@click:prepend="selectSerials()"
></v-textarea>
</v-col>
@@ -386,16 +386,16 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="partAssemblyDialog">
<v-dialog v-model="partAssemblyDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedPartAssembly"
v-model="selectedPartAssembly"
:aya-type="$ay.ayt().PartAssembly"
show-edit-icon
v-model="selectedPartAssembly"
:label="$ay.t('PartAssemblyList')"
ref="selectedPartAssembly"
data-cy="selectedPartAssembly"
></gz-pick-list>
@@ -404,16 +404,16 @@
pvm.useInventory &&
form().showMe(this, 'WorkOrderItemPartPartWarehouseID')
"
ref="selectedPartWarehouse"
v-model="selectedPartWarehouse"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
v-model="selectedPartWarehouse"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
ref="selectedPartWarehouse"
data-cy="selectedPartWarehouse"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="partAssemblyDialog = false" color="primary">{{
<v-btn text color="primary" @click="partAssemblyDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -421,8 +421,8 @@
:disabled="selectedPartAssembly == null"
color="primary"
text
@click="addPartAssembly()"
class="ml-4"
@click="addPartAssembly()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -435,10 +435,10 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="serialDialog">
<v-dialog v-model="serialDialog" persistent max-width="600px">
<v-card>
<v-card-title>
<v-btn text @click="serialDialog = false" color="primary">{{
<v-btn text color="primary" @click="serialDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -466,21 +466,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
props: {
value: {
default: null,
@@ -499,6 +484,308 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -523,6 +810,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
generateUnit() {
const thisPart = this.value.items[this.activeWoItemIndex].parts[
@@ -828,296 +1118,6 @@ export default {
return ret;
}
//---
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
}
};
</script>

View File

@@ -71,10 +71,10 @@
<!-- ################################ SCHEDULED USERS TABLE ############################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -83,9 +83,9 @@
data-cy="scheduledUsersTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -95,8 +95,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -109,16 +109,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.startDate
"
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
data-cy="startDate"
:error-messages="
form().serverErrors(
@@ -142,16 +142,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.stopDate
"
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
data-cy="stopDate"
:rules="[
form().datePrecedence(
@@ -184,6 +184,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.estimatedQuantity
@@ -193,9 +196,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserEstimatedQuantity')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
data-cy="scheduledUsers.EstimatedQuantity"
:error-messages="
form().serverErrors(
@@ -229,21 +229,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserUserID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
data-cy="scheduledUsers.userid"
:error-messages="
form().serverErrors(
@@ -268,21 +268,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
data-cy="scheduledUsers.serviceRateId"
:error-messages="
form().serverErrors(
@@ -304,15 +304,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -331,6 +322,136 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -355,6 +476,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
convertAllToLabor() {
this.value.items[this.activeWoItemIndex].scheduledUsers.forEach(z => {
@@ -574,130 +698,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
}
};
</script>

View File

@@ -55,10 +55,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -67,9 +67,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -79,8 +79,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -93,15 +93,15 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].sequence
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:label="$ay.t('Sequence')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
:rules="[
form().integerValid(
this,
@@ -114,12 +114,12 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
></v-text-field>
</v-col>
@@ -136,6 +136,9 @@
xl="3"
>
<v-select
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].status
"
@@ -145,9 +148,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskWorkOrderItemTaskCompletionType')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
data-cy="usertype"
:rules="[
form().integerValid(
@@ -178,21 +178,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedByUserId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskUser')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
data-cy="expenseUser"
:error-messages="
form().serverErrors(
@@ -217,16 +217,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedDate
"
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
data-cy="travelCompletedDate"
:error-messages="
form().serverErrors(
@@ -244,6 +244,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemTaskTaskID')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
v-model="value.items[activeWoItemIndex].tasks[activeItemIndex].task"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -260,14 +261,13 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
]"
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
data-cy="task"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -277,21 +277,21 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="taskGroupDialog">
<v-dialog v-model="taskGroupDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedTaskGroup"
v-model="selectedTaskGroup"
:aya-type="$ay.ayt().TaskGroup"
show-edit-icon
v-model="selectedTaskGroup"
:label="$ay.t('TaskGroupList')"
ref="selectedTaskGroup"
data-cy="selectedTaskGroup"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="taskGroupDialog = false" color="primary">{{
<v-btn text color="primary" @click="taskGroupDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -299,8 +299,8 @@
:disabled="selectedTaskGroup == null"
color="primary"
text
@click="addTaskGroup()"
class="ml-4"
@click="addTaskGroup()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -312,17 +312,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
props: {
value: {
default: null,
@@ -341,6 +330,127 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -365,6 +475,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
async addTaskGroup() {
const res = await window.$gz.api.get(
@@ -532,119 +645,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="travelsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,16 +87,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStartDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStartDate
"
:label="$ay.t('WorkOrderItemTravelStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
data-cy="travelStartDate"
:error-messages="
form().serverErrors(
@@ -120,16 +120,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStopDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStopDate
"
:label="$ay.t('WorkOrderItemTravelStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
data-cy="travelStopDate"
:rules="[
form().datePrecedence(
@@ -160,6 +160,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateQuantity
@@ -167,9 +170,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
data-cy="travelTravelRateQuantity"
:error-messages="
form().serverErrors(
@@ -202,15 +202,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].distance
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelDistance')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
data-cy="travelTravelRateDistance"
:error-messages="
form().serverErrors(
@@ -243,19 +243,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateId
"
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
data-cy="travels.travelRateId"
:error-messages="
form().serverErrors(
@@ -280,20 +280,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelUserID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
data-cy="travels.userid"
:error-messages="
form().serverErrors(
@@ -318,6 +318,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.noChargeQuantity
@@ -325,9 +328,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
data-cy="travelNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -364,18 +364,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
data-cy="travelTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -403,6 +403,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.priceOverride
@@ -411,9 +414,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
data-cy="travelpriceoverride"
:error-messages="
form().serverErrors(
@@ -440,6 +440,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelDetails
@@ -453,16 +456,13 @@
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
data-cy="traveltravelDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -471,15 +471,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -498,225 +489,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId: null,
price: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1015,6 +792,229 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId: null,
price: 0,
priceOverride: null,
isDirty: true,
quoteItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -57,10 +57,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -69,9 +69,9 @@
data-cy="unitsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -81,8 +81,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -94,20 +94,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].unitId
"
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
data-cy="units.unitId"
:rules="[
form().required(
@@ -166,6 +166,7 @@
cols="12"
>
<v-textarea
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].notes
"
@@ -178,14 +179,13 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
data-cy="unitUnitNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
@@ -197,6 +197,7 @@
cols="12"
>
<gz-tag-picker
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].tags"
:readonly="formState.readOnly"
data-cy="unitTags"
@@ -206,7 +207,6 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
@@ -217,6 +217,9 @@
<v-col v-if="!value.userIsRestrictedType" cols="12">
<gz-custom-fields
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].customFields
"
@@ -224,9 +227,6 @@
:readonly="formState.readOnly"
:parent-v-m="this"
key-start-with="WorkOrderItemUnitCustom"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
data-cy="unitCustomFields"
:error-messages="
form().serverErrors(
@@ -250,10 +250,10 @@
cols="12"
>
<gz-wiki
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].wiki`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].wiki"
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:readonly="formState.readOnly"
@input="
fieldValueChanged(
@@ -284,22 +284,22 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="bulkUnitsDialog">
<v-dialog v-model="bulkUnitsDialog" persistent max-width="600px">
<v-card>
<v-card-title>{{ $ay.t("AddMultipleUnits") }}</v-card-title>
<v-card-text>
<gz-tag-picker v-model="selectedBulkUnitTags"></gz-tag-picker>
<gz-pick-list
v-model="selectedBulkUnitCustomer"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="false"
v-model="selectedBulkUnitCustomer"
:label="$ay.t('Customer')"
:can-clear="true"
></gz-pick-list>
<v-data-table
dense
v-model="selectedBulkUnits"
dense
:headers="bulkUnitTableHeaders"
:items="availableBulkUnits"
class="my-10"
@@ -312,7 +312,7 @@
</v-data-table>
</v-card-text>
<v-card-actions>
<v-btn text @click="bulkUnitsDialog = false" color="primary">{{
<v-btn text color="primary" @click="bulkUnitsDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -339,21 +339,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
props: {
value: {
default: null,
@@ -376,6 +361,126 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -400,6 +505,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
async updateContractIfApplicable() {
const id = this.value.items[this.activeWoItemIndex].units[
@@ -689,114 +797,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

View File

@@ -164,10 +164,10 @@
<!-- ################################ WORK ORDER ITEMS TABLE ############################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -176,9 +176,9 @@
data-cy="itemsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.status`]="{ item }">
<template v-if="item.status.id != null">
@@ -209,8 +209,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -220,6 +220,7 @@
cols="12"
>
<v-textarea
:ref="`items[${activeItemIndex}].notes`"
v-model="value.items[activeItemIndex].notes"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -227,11 +228,10 @@
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].notes`)
"
:ref="`items[${activeItemIndex}].notes`"
:rules="[form().required(this, `items[${activeItemIndex}].notes`)]"
data-cy="Items.Notes"
@input="fieldValueChanged(`items[${activeItemIndex}].notes`)"
auto-grow
@input="fieldValueChanged(`items[${activeItemIndex}].notes`)"
></v-textarea>
</v-col>
@@ -246,24 +246,25 @@
xl="3"
>
<v-text-field
:ref="`items[${activeItemIndex}].sequence`"
v-model="value.items[activeItemIndex].sequence"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:label="$ay.t('Sequence')"
:ref="`items[${activeItemIndex}].sequence`"
:rules="[
form().integerValid(this, `items[${activeItemIndex}].sequence`)
]"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].sequence`)
"
@input="fieldValueChanged(`items[${activeItemIndex}].sequence`)"
type="number"
@input="fieldValueChanged(`items[${activeItemIndex}].sequence`)"
></v-text-field>
</v-col>
<v-col v-if="form().showMe(this, 'WorkOrderItemTechNotes')" cols="12">
<v-textarea
:ref="`items[${activeItemIndex}].techNotes`"
v-model="value.items[activeItemIndex].techNotes"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -271,10 +272,9 @@
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].techNotes`)
"
:ref="`items[${activeItemIndex}].techNotes`"
data-cy="items.techNotes"
@input="fieldValueChanged(`items[${activeItemIndex}].techNotes`)"
auto-grow
@input="fieldValueChanged(`items[${activeItemIndex}].techNotes`)"
></v-textarea>
</v-col>
@@ -289,11 +289,11 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemRequestDate')"
:ref="`items[${activeItemIndex}].requestDate`"
v-model="value.items[activeItemIndex].requestDate"
:label="$ay.t('WorkOrderItemRequestDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="`items[${activeItemIndex}].requestDate`"
data-cy="requestDate"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].requestDate`)
@@ -313,10 +313,10 @@
xl="3"
>
<v-autocomplete
:ref="`items[${activeItemIndex}].workOrderItemStatusId`"
v-model="value.items[activeItemIndex].workOrderItemStatusId"
:readonly="formState.readOnly"
:disabled="isDeleted"
@input="fieldValueChanged('workOrderItemStatusId')"
:items="selectableStatusList"
item-text="name"
item-value="id"
@@ -327,9 +327,9 @@
`items[${activeItemIndex}].workOrderItemStatusId`
)
"
:ref="`items[${activeItemIndex}].workOrderItemStatusId`"
data-cy="workOrderItemStatusId"
prepend-icon="$ayiEdit"
@input="fieldValueChanged('workOrderItemStatusId')"
@click:prepend="handleEditItemStatusClick()"
>
<template v-slot:selection="{ item }">
@@ -369,10 +369,10 @@
xl="3"
>
<v-autocomplete
:ref="`items[${activeItemIndex}].workOrderItemPriorityId`"
v-model="value.items[activeItemIndex].workOrderItemPriorityId"
:readonly="formState.readOnly"
:disabled="isDeleted"
@input="fieldValueChanged('workOrderItemPriorityId')"
:items="selectablePriorityList"
item-text="name"
item-value="id"
@@ -383,9 +383,9 @@
`items[${activeItemIndex}].workOrderItemPriorityId`
)
"
:ref="`items[${activeItemIndex}].workOrderItemPriorityId`"
data-cy="workOrderItemPriorityId"
prepend-icon="$ayiEdit"
@input="fieldValueChanged('workOrderItemPriorityId')"
@click:prepend="handleEditItemPriorityClick()"
>
<template v-slot:selection="{ item }">
@@ -424,11 +424,11 @@
xl="3"
>
<v-checkbox
:ref="`items[${activeItemIndex}].warrantyService`"
v-model="value.items[activeItemIndex].warrantyService"
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemWarrantyService')"
:ref="`items[${activeItemIndex}].warrantyService`"
data-cy="warrantyService"
:error-messages="
form().serverErrors(
@@ -448,9 +448,9 @@
cols="12"
>
<gz-tag-picker
:ref="`items[${activeItemIndex}].tags`"
v-model="value.items[activeItemIndex].tags"
:readonly="formState.readOnly"
:ref="`items[${activeItemIndex}].tags`"
data-cy="tags"
:error-messages="
form().serverErrors(this, `items[${activeItemIndex}].tags`)
@@ -461,12 +461,12 @@
<v-col v-if="!value.userIsRestrictedType" cols="12">
<gz-custom-fields
:ref="`items[${activeItemIndex}].customFields`"
v-model="value.items[activeItemIndex].customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly"
:parent-v-m="this"
key-start-with="WorkOrderItemCustom"
:ref="`items[${activeItemIndex}].customFields`"
data-cy="customFields"
:error-messages="
form().serverErrors(
@@ -486,10 +486,10 @@
cols="12"
>
<gz-wiki
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:ref="`items[${activeItemIndex}].wiki`"
v-model="value.items[activeItemIndex].wiki"
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -514,7 +514,7 @@
GRANDCHILDREN
############################################################################ -->
<v-col cols="12" v-show="showUnits">
<v-col v-show="showUnits" cols="12">
<GzQuoteItemUnits
v-model="value"
:pvm="pvm"
@@ -525,7 +525,7 @@
/>
</v-col>
<v-col cols="12" v-show="showScheduledUsers">
<v-col v-show="showScheduledUsers" cols="12">
<GzQuoteItemScheduledUsers
v-model="value"
:pvm="pvm"
@@ -535,7 +535,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showTasks">
<v-col v-show="showTasks" cols="12">
<GzQuoteItemTasks
v-model="value"
:pvm="pvm"
@@ -546,7 +546,7 @@
/>
</v-col>
<v-col cols="12" v-show="showParts">
<v-col v-show="showParts" cols="12">
<GzQuoteItemParts
v-model="value"
:pvm="pvm"
@@ -557,7 +557,7 @@
/>
</v-col>
<v-col cols="12" v-show="showLabors">
<v-col v-show="showLabors" cols="12">
<GzQuoteItemLabors
v-model="value"
:pvm="pvm"
@@ -567,7 +567,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showTravels">
<v-col v-show="showTravels" cols="12">
<GzQuoteItemTravels
v-model="value"
:pvm="pvm"
@@ -577,7 +577,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showExpenses">
<v-col v-show="showExpenses" cols="12">
<GzQuoteItemExpenses
v-model="value"
:pvm="pvm"
@@ -588,7 +588,7 @@
/>
</v-col>
<v-col cols="12" v-show="showLoans">
<v-col v-show="showLoans" cols="12">
<GzQuoteItemLoans
v-model="value"
:pvm="pvm"
@@ -598,7 +598,7 @@
@change="$emit('change')"
/>
</v-col>
<v-col cols="12" v-show="showOutsideServices">
<v-col v-show="showOutsideServices" cols="12">
<GzQuoteItemOutsideServices
v-model="value"
:pvm="pvm"
@@ -635,8 +635,19 @@ export default {
GzQuoteItemLoans,
GzQuoteItemOutsideServices
},
created() {
this.setDefaultView();
props: {
value: {
default: null,
type: Object
},
pvm: {
default: null,
type: Object
},
goto: {
default: null,
type: Object
}
},
data() {
return {
@@ -653,308 +664,6 @@ export default {
gotoUnitIndex: null
};
},
props: {
value: {
default: null,
type: Object
},
pvm: {
default: null,
type: Object
},
goto: {
default: null,
type: Object
}
},
watch: {
goto(val, oldVal) {
if (val != oldVal) {
const navto = { woitemindex: null, childindex: null };
//find the item in question then trigger the nav
let keepgoing = true;
this.value.items.forEach((z, itemindex) => {
if (keepgoing) {
switch (val.type) {
case window.$gz.type.QuoteItem:
if (z.id == val.id) {
navto.woitemindex = itemindex;
keepgoing = false;
}
break;
case window.$gz.type.QuoteItemOutsideService:
z.outsideServices.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemExpense:
z.expenses.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemLabor:
z.labors.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemLoan:
z.loans.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemPart:
z.parts.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemScheduledUser:
z.scheduledUsers.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemTask:
z.tasks.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemTravel:
z.travels.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemUnit:
z.units.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
}
}
});
if (navto.woitemindex != null) {
this.selectedRow = [{ index: navto.woitemindex }];
this.activeItemIndex = navto.woitemindex;
this.$nextTick(() => {
const el = this.$refs.topform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
if (navto.childindex != null) {
this.$nextTick(() => {
switch (val.type) {
case window.$gz.type.QuoteItemOutsideService:
this.gotoOutsideServiceIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemExpense:
this.gotoExpenseIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemLabor:
this.gotoLaborIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemLoan:
this.gotoLoanIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemPart:
this.gotoPartIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemTask:
this.gotoTaskIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemScheduledUser:
this.gotoScheduledUserIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemTravel:
this.gotoTravelIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemUnit:
this.gotoUnitIndex = navto.childindex;
break;
}
});
}
}
}
}
},
methods: {
newItem() {
const newIndex = this.value.items.length;
this.value.items.push({
id: 0,
concurrency: 0,
notes: undefined, //to trigger validation on new
wiki: null,
customFields: "{}",
tags: [],
quoteId: this.value.id,
techNotes: null,
workOrderItemStatusId: null,
workOrderItemPriorityId: null,
requestDate: null,
warrantyService: false,
sequence: newIndex + 1, //indexes are zero based but sequences are visible to user so 1 based
isDirty: true,
expenses: [],
labors: [],
loans: [],
parts: [],
scheduledUsers: [],
tasks: [],
travels: [],
units: [],
outsideServices: [],
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeItemIndex].notes = null;
this.fieldValueChanged(`items[${this.activeItemIndex}].notes`);
});
},
newSubItem(atype) {
//new Id value to use (by convention goto negative will trigger create and then goto instead of simple goto)
const newId = -Math.abs(Date.now());
switch (atype) {
case window.$gz.type.WorkOrderItemOutsideService:
this.gotoOutsideServiceIndex = newId;
break;
case window.$gz.type.WorkOrderItemExpense:
this.gotoExpenseIndex = newId;
break;
case window.$gz.type.WorkOrderItemLabor:
this.gotoLaborIndex = newId;
break;
case window.$gz.type.WorkOrderItemLoan:
this.gotoLoanIndex = newId;
break;
case window.$gz.type.WorkOrderItemPart:
this.gotoPartIndex = newId;
break;
case window.$gz.type.WorkOrderItemTask:
this.gotoTaskIndex = newId;
break;
case window.$gz.type.WorkOrderItemScheduledUser:
this.gotoScheduledUserIndex = newId;
break;
case window.$gz.type.WorkOrderItemTravel:
this.gotoTravelIndex = newId;
break;
case window.$gz.type.WorkOrderItemUnit:
this.gotoUnitIndex = newId;
break;
}
},
unDeleteItem() {
this.value.items[this.activeItemIndex].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeItemIndex].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items.forEach(z => (z.deleted = true));
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value && this.value.items && this.value.items.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
handleEditItemStatusClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemStatus,
id: this.value.items[this.activeItemIndex].workOrderItemStatusId
});
},
handleEditItemPriorityClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemPriority,
id: this.value.items[this.activeItemIndex].workOrderItemPriorityId
});
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeItemIndex].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted = this.value.items[item.index].deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
},
computed: {
isDeleted: function() {
if (this.value.items[this.activeItemIndex] == null) {
@@ -1218,6 +927,297 @@ export default {
!this.value.userIsRestrictedType
);
}
},
watch: {
goto(val, oldVal) {
if (val != oldVal) {
const navto = { woitemindex: null, childindex: null };
//find the item in question then trigger the nav
let keepgoing = true;
this.value.items.forEach((z, itemindex) => {
if (keepgoing) {
switch (val.type) {
case window.$gz.type.QuoteItem:
if (z.id == val.id) {
navto.woitemindex = itemindex;
keepgoing = false;
}
break;
case window.$gz.type.QuoteItemOutsideService:
z.outsideServices.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemExpense:
z.expenses.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemLabor:
z.labors.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemLoan:
z.loans.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemPart:
z.parts.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemScheduledUser:
z.scheduledUsers.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemTask:
z.tasks.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemTravel:
z.travels.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
case window.$gz.type.QuoteItemUnit:
z.units.forEach((x, childindex) => {
if (x.id == val.id) {
navto.woitemindex = itemindex;
navto.childindex = childindex;
keepgoing = false;
}
});
break;
}
}
});
if (navto.woitemindex != null) {
this.selectedRow = [{ index: navto.woitemindex }];
this.activeItemIndex = navto.woitemindex;
this.$nextTick(() => {
const el = this.$refs.topform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
if (navto.childindex != null) {
this.$nextTick(() => {
switch (val.type) {
case window.$gz.type.QuoteItemOutsideService:
this.gotoOutsideServiceIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemExpense:
this.gotoExpenseIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemLabor:
this.gotoLaborIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemLoan:
this.gotoLoanIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemPart:
this.gotoPartIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemTask:
this.gotoTaskIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemScheduledUser:
this.gotoScheduledUserIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemTravel:
this.gotoTravelIndex = navto.childindex;
break;
case window.$gz.type.QuoteItemUnit:
this.gotoUnitIndex = navto.childindex;
break;
}
});
}
}
}
}
},
created() {
this.setDefaultView();
},
methods: {
newItem() {
const newIndex = this.value.items.length;
this.value.items.push({
id: 0,
concurrency: 0,
notes: undefined, //to trigger validation on new
wiki: null,
customFields: "{}",
tags: [],
quoteId: this.value.id,
techNotes: null,
workOrderItemStatusId: null,
workOrderItemPriorityId: null,
requestDate: null,
warrantyService: false,
sequence: newIndex + 1, //indexes are zero based but sequences are visible to user so 1 based
isDirty: true,
expenses: [],
labors: [],
loans: [],
parts: [],
scheduledUsers: [],
tasks: [],
travels: [],
units: [],
outsideServices: [],
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeItemIndex].notes = null;
this.fieldValueChanged(`items[${this.activeItemIndex}].notes`);
});
},
newSubItem(atype) {
//new Id value to use (by convention goto negative will trigger create and then goto instead of simple goto)
const newId = -Math.abs(Date.now());
switch (atype) {
case window.$gz.type.WorkOrderItemOutsideService:
this.gotoOutsideServiceIndex = newId;
break;
case window.$gz.type.WorkOrderItemExpense:
this.gotoExpenseIndex = newId;
break;
case window.$gz.type.WorkOrderItemLabor:
this.gotoLaborIndex = newId;
break;
case window.$gz.type.WorkOrderItemLoan:
this.gotoLoanIndex = newId;
break;
case window.$gz.type.WorkOrderItemPart:
this.gotoPartIndex = newId;
break;
case window.$gz.type.WorkOrderItemTask:
this.gotoTaskIndex = newId;
break;
case window.$gz.type.WorkOrderItemScheduledUser:
this.gotoScheduledUserIndex = newId;
break;
case window.$gz.type.WorkOrderItemTravel:
this.gotoTravelIndex = newId;
break;
case window.$gz.type.WorkOrderItemUnit:
this.gotoUnitIndex = newId;
break;
}
},
unDeleteItem() {
this.value.items[this.activeItemIndex].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeItemIndex].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items.forEach(z => (z.deleted = true));
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value && this.value.items && this.value.items.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
handleEditItemStatusClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemStatus,
id: this.value.items[this.activeItemIndex].workOrderItemStatusId
});
},
handleEditItemPriorityClick: function() {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.WorkOrderItemPriority,
id: this.value.items[this.activeItemIndex].workOrderItemPriorityId
});
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeItemIndex].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted = this.value.items[item.index].deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};

View File

@@ -14,10 +14,10 @@
pvm.currentState.name
}}</span>
<v-icon :color="pvm.currentState.color" class="ml-4">$ayiFlag</v-icon>
<v-icon color="primary" v-if="pvm.currentState.locked" class="ml-4"
<v-icon v-if="pvm.currentState.locked" color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon color="primary" v-if="pvm.currentState.completed" class="ml-4"
<v-icon v-if="pvm.currentState.completed" color="primary" class="ml-4"
>$ayiCheckCircle</v-icon
>
</div>
@@ -37,10 +37,10 @@
<span class="ml-3">{{ item.user }}</span>
<span class="font-weight-bold ml-3">{{ item.name }}</span>
<v-icon small :color="item.color" class="ml-4">$ayiFlag</v-icon>
<v-icon small color="primary" v-if="item.locked" class="ml-4"
<v-icon v-if="item.locked" small color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon small color="primary" v-if="item.completed" class="ml-4"
<v-icon v-if="item.completed" small color="primary" class="ml-4"
>$ayiCheckCircle</v-icon
>
</div>
@@ -55,13 +55,13 @@
<v-icon small :color="item.color" class="ml-4"
>$ayiFlag</v-icon
>
<v-icon small color="primary" v-if="item.locked" class="ml-4"
<v-icon v-if="item.locked" small color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon
v-if="item.completed"
small
color="primary"
v-if="item.completed"
class="ml-4"
>$ayiCheckCircle</v-icon
>
@@ -92,17 +92,17 @@
data.item.name
}}</span
><v-icon
v-if="data.item.locked"
small
color="disabled"
class="ml-2"
v-if="data.item.locked"
>$ayiLock</v-icon
>
<v-icon
v-if="data.item.completed"
color="disabled"
class="ml-1"
small
v-if="data.item.completed"
>$ayiCheckCircle</v-icon
></v-list-item-title
>
@@ -137,13 +137,6 @@
</template>
<script>
export default {
data() {
return {
selectedStatus: null,
openDialog: false
};
},
props: {
value: {
default: null,
@@ -165,6 +158,53 @@ export default {
readonly: Boolean,
disabled: Boolean
},
data() {
return {
selectedStatus: null,
openDialog: false
};
},
computed: {
hasState() {
return this.value.states != null && this.value.states.length > 0;
},
stateDisplayList() {
const ret = [];
this.value.states.forEach(z => {
ret.push(this.getStateForDisplay(z));
});
return ret;
},
canAdd: function() {
//first check most obvious disqualifying properties
if (!this.pvm.rights.change) {
return false;
}
//not currently locked, user has rights to do it so allow it
if (!this.value.isLockedAtServer) {
return true;
}
//locked, confirm if user can change it
//if any role then no problem
//ok, only thing left to check is if the current user can unlock this
//get remove roles required for current state
const cs = this.pvm.currentState;
if (cs.removeRoles == null || cs.removeRoles == 0) {
//no state set yet
return true;
}
//ok, need to check the role here against current user roles to see if this is valid
if (window.$gz.role.hasRole(cs.removeRoles)) {
return true;
}
return false;
}
},
methods: {
addState() {
@@ -249,47 +289,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
hasState() {
return this.value.states != null && this.value.states.length > 0;
},
stateDisplayList() {
const ret = [];
this.value.states.forEach(z => {
ret.push(this.getStateForDisplay(z));
});
return ret;
},
canAdd: function() {
//first check most obvious disqualifying properties
if (!this.pvm.rights.change) {
return false;
}
//not currently locked, user has rights to do it so allow it
if (!this.value.isLockedAtServer) {
return true;
}
//locked, confirm if user can change it
//if any role then no problem
//ok, only thing left to check is if the current user can unlock this
//get remove roles required for current state
const cs = this.pvm.currentState;
if (cs.removeRoles == null || cs.removeRoles == 0) {
//no state set yet
return true;
}
//ok, need to check the role here against current user roles to see if this is valid
if (window.$gz.role.hasRole(cs.removeRoles)) {
return true;
}
return false;
}
}
};
</script>

View File

@@ -2,11 +2,11 @@
<div>
<v-row justify="center">
<v-dialog
v-model="isVisible"
scrollable
max-width="600px"
v-model="isVisible"
@keydown.esc="cancel"
data-cy="reportselector"
@keydown.esc="cancel"
>
<v-card elevation="24">
<v-card-title class="text-h5 lighten-2" primary-title>
@@ -34,17 +34,17 @@
v-if="rights.change"
color="primary"
text
@click.native="newReport"
data-cy="reportselector:ok"
class="d-none d-sm-flex"
@click.native="newReport"
>{{ $ay.t("New") }}</v-btn
>
<v-spacer v-if="!$vuetify.breakpoint.xs"></v-spacer>
<v-btn
color="primary"
text
@click.native="cancel"
data-cy="reportselector:cancel"
@click.native="cancel"
>{{ $ay.t("Cancel") }}</v-btn
>
</v-card-actions>
@@ -56,7 +56,7 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="360px" v-model="jobActive">
<v-dialog v-model="jobActive" persistent max-width="360px">
<v-card>
<v-card-title>{{ $ay.t("RenderingReport") }}</v-card-title>
<v-card-text>
@@ -70,7 +70,7 @@
</div>
</v-card-text>
<v-card-actions>
<v-btn text @click="cancelJob" color="primary">{{
<v-btn text color="primary" @click="cancelJob">{{
$ay.t("Cancel")
}}</v-btn>
</v-card-actions>

View File

@@ -7,17 +7,47 @@
chips
deletable-chips
:value="selectedValue"
@input="handleInput"
:readonly="readonly"
:disabled="disabled"
:label="label"
:rules="rules"
:error-messages="errorMessages"
:data-cy="'roleinput:' + testId"
@input="handleInput"
></v-select>
</template>
<script>
export default {
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
errorMessages: { type: Array, default: null },
value: { type: Number, default: 0 },
readonly: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
limitSelectionTo: { type: String, default: null }, //"inside" - no customer roles, "outside" - no non-customer roles
testId: { type: String, default: null }
},
data() {
return {
internalValue: null,
availableRoles: []
};
},
computed: {
selectedValue() {
const ret = [];
if (this.value != null && this.value != 0) {
for (let i = 0; i < this.availableRoles.length; i++) {
const role = this.availableRoles[i];
if (this.value & role.id) {
ret.push(role.id);
}
}
}
return ret;
}
},
async created() {
await window.$gz.enums.fetchEnumList("AuthorizationRoles");
const rawRoles = window.$gz.enums.getSelectionList("AuthorizationRoles");
@@ -36,36 +66,6 @@ export default {
}
}
},
data() {
return {
internalValue: null,
availableRoles: []
};
},
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
errorMessages: { type: Array, default: null },
value: { type: Number, default: 0 },
readonly: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
limitSelectionTo: { type: String, default: null }, //"inside" - no customer roles, "outside" - no non-customer roles
testId: { type: String, default: null }
},
computed: {
selectedValue() {
const ret = [];
if (this.value != null && this.value != 0) {
for (let i = 0; i < this.availableRoles.length; i++) {
const role = this.availableRoles[i];
if (!!(this.value & role.id)) {
ret.push(role.id);
}
}
}
return ret;
}
},
methods: {
handleInput(value) {
let newValue = 0;

View File

@@ -1,11 +1,10 @@
<template>
<div>
<span class="text-caption" v-if="!noLabel">
<span v-if="!noLabel" class="text-caption">
{{ title }}
</span>
<v-autocomplete
:value="value"
@input="input($event)"
:readonly="readonly"
:items="sourcetags"
:loading="tagSearchUnderway"
@@ -23,10 +22,11 @@
cache-items
:rules="rules"
:error-messages="errorMessages"
@input="input($event)"
>
<template slot="no-data" v-if="offerAdd()">
<template v-if="offerAdd()" slot="no-data">
<v-chip color="primary" text-color="white" class="text-h4">
{{ this.normalizeTag(tagSearchEntry) }}</v-chip
{{ normalizeTag(tagSearchEntry) }}</v-chip
>
<v-btn large icon @click="addTag()">
<v-icon large color="success">$ayiPlusCircle</v-icon>
@@ -37,21 +37,6 @@
</template>
<script>
export default {
created() {
//Set the initial list items based on the record items, this only needs to be called once at init
if (!this.initialized && this.value != null && this.value.length > 0) {
this.sourcetags = this.value;
this.initialized = true;
}
},
data() {
return {
sourcetags: [],
tagSearchEntry: null,
tagSearchUnderway: false,
initialized: false
};
},
props: {
value: {
default() {
@@ -87,27 +72,13 @@ export default {
}
}
},
watch: {
async tagSearchEntry(val) {
if (!val || this.tagSearchUnderway) {
return;
}
this.tagSearchUnderway = true;
try {
const res = await window.$gz.api.get("tag-list/list?query=" + val);
//We never expect there to be no data here
if (!res.hasOwnProperty("data")) {
throw new Error(res);
}
//adding this to the property will automatically have it cached by the autocomplete component
//as cache-items has been set so this just needs to be set here once and all is well in future
//Any search will be kept for later so this is very efficient
this.sourcetags = res.data;
this.tagSearchUnderway = false;
} catch (err) {
window.$gz.errorHandler.handleFormError(err);
}
}
data() {
return {
sourcetags: [],
tagSearchEntry: null,
tagSearchUnderway: false,
initialized: false
};
},
computed: {
title() {
@@ -123,6 +94,35 @@ export default {
return this.$ay.t("TypeToSearchOrAdd");
}
},
watch: {
async tagSearchEntry(val) {
if (!val || this.tagSearchUnderway) {
return;
}
this.tagSearchUnderway = true;
try {
const res = await window.$gz.api.get("tag-list/list?query=" + val);
//We never expect there to be no data here
if (!Object.prototype.hasOwnProperty.call(res, "data")) {
throw new Error(res);
}
//adding this to the property will automatically have it cached by the autocomplete component
//as cache-items has been set so this just needs to be set here once and all is well in future
//Any search will be kept for later so this is very efficient
this.sourcetags = res.data;
this.tagSearchUnderway = false;
} catch (err) {
window.$gz.errorHandler.handleFormError(err);
}
}
},
created() {
//Set the initial list items based on the record items, this only needs to be called once at init
if (!this.initialized && this.value != null && this.value.length > 0) {
this.sourcetags = this.value;
this.initialized = true;
}
},
methods: {
offerAdd() {
if (

View File

@@ -7,13 +7,13 @@
<v-dialog v-model="dlgtime" width="300px">
<template v-slot:activator="{ on }">
<v-text-field
v-on="on"
:value="readonlyFormat()"
:label="label"
prepend-icon="$ayiClock"
@click:prepend="dlgtime = true"
readonly
:error="!!hasErrors"
v-on="on"
@click:prepend="dlgtime = true"
></v-text-field>
</template>
<v-time-picker
@@ -42,11 +42,11 @@
<v-text-field
ref="timeField"
:value="timeValue"
@change="updateTimeValue"
:readonly="readonly"
:disabled="disabled"
type="time"
:data-cy="`${dataCy}:time`"
@change="updateTimeValue"
></v-text-field>
</v-col>
</template>
@@ -73,12 +73,6 @@
//NOTE: this control also captures the date even though it's time only
//this is an intentional design decision to support field change to date or date AND time and is considered a display issue
export default {
data: () => ({
dlgtime: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
}),
props: {
label: { type: String, default: null },
rules: { type: Array, default: undefined },
@@ -88,6 +82,12 @@ export default {
disabled: { type: Boolean, default: false },
dataCy: { type: String, default: null }
},
data: () => ({
dlgtime: false,
timeZoneName: window.$gz.locale.getResolvedTimeZoneName(),
languageName: window.$gz.locale.getResolvedLanguage(),
hour12: window.$gz.locale.getHour12()
}),
computed: {
hasErrors() {
return this.errorMessages != null && this.errorMessages.length > 0;

View File

@@ -1,9 +1,9 @@
<template>
<v-text-field
v-bind="$attrs"
v-on="$listeners"
type="url"
prepend-icon="$ayiExternalLinkAlt"
v-on="$listeners"
@click:prepend="openUrl"
></v-text-field>
</template>

View File

@@ -4,10 +4,10 @@
<v-btn
depressed
tile
@click="toggleReveal"
:color="isEmpty ? null : 'primary'"
@click="toggleReveal"
>
Wiki<v-icon v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'" right></v-icon
Wiki<v-icon right v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"></v-icon
></v-btn>
</div>
<template v-if="reveal">
@@ -23,8 +23,8 @@
<v-btn
text
:outlined="currentView == view.DESIGN_VIEW"
@click="currentView = view.DESIGN_VIEW"
data-cy="wikiDesignView"
@click="currentView = view.DESIGN_VIEW"
>
<v-icon>$ayiEdit</v-icon>
</v-btn>
@@ -38,7 +38,7 @@
</div>
</template>
<v-sheet
v-if="currentView != this.view.HIDDEN_VIEW"
v-if="currentView != view.HIDDEN_VIEW"
elevation="2"
class="aywiki pa-2 pa-sm-6 mt-2"
>
@@ -131,20 +131,20 @@
<div class="ma-8">
<v-slider
v-model="tableMenuColumns"
thumb-size="24"
thumb-label="always"
v-model="tableMenuColumns"
min="1"
max="10"
prepend-icon="$ayiArrowsAltH"
></v-slider>
<v-slider
v-model="tableMenuRows"
prepend-icon="$ayiArrowsAltV"
class="mt-8"
thumb-size="24"
thumb-label="always"
v-model="tableMenuRows"
min="1"
max="15"
></v-slider>
@@ -169,8 +169,8 @@
<v-icon>$ayiLink</v-icon>
</v-btn>
<v-menu
min-width="300"
v-model="linkMenu"
min-width="300"
:close-on-content-click="false"
offset-y
:position-x="menuX"
@@ -211,8 +211,8 @@
<v-icon>$ayiImage</v-icon>
</v-btn>
<v-menu
min-width="360"
v-model="imageMenu"
min-width="360"
:close-on-content-click="false"
offset-y
:position-x="menuX"
@@ -240,13 +240,13 @@
<v-tab-item key="file"
><div class="ma-6">
<v-select
@click="getAttachments"
:label="$ay.t('Attachments')"
v-model="selectedImageAttachment"
:label="$ay.t('Attachments')"
:items="attachments"
item-text="name"
item-value="id"
return-object
@click="getAttachments"
></v-select>
<v-text-field
@@ -297,16 +297,16 @@
<div :style="editStyle()">
<v-textarea
v-cloak
@drop.prevent="onDrop"
@dragover.prevent
ref="editArea"
v-model="localVal"
solo
no-resize
:height="editAreaHeight"
ref="editArea"
data-cy="wikiEditor"
@drop.prevent="onDrop"
@dragover.prevent
@input="handleInput"
@dblclick="handleDoubleClick"
v-model="localVal"
data-cy="wikiEditor"
></v-textarea>
</div>
</v-col>
@@ -324,8 +324,8 @@
</v-row>
<v-btn depressed tile @click="toggleReveal">
Wiki<v-icon
v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"
right
v-text="reveal ? '$ayiEyeSlash' : '$ayiEye'"
></v-icon
></v-btn>
</v-sheet>
@@ -336,27 +336,11 @@
import marked from "marked";
import DOMPurify from "dompurify";
export default {
created() {
// Add a hook to make all links open a new window
//https://github.com/cure53/DOMPurify/blob/master/demos/hooks-target-blank-demo.html
DOMPurify.addHook("afterSanitizeAttributes", function(node) {
// set all elements owning target to target=_blank
if ("target" in node) {
node.setAttribute("target", "_blank");
// prevent https://www.owasp.org/index.php/Reverse_Tabnabbing
node.setAttribute("rel", "noopener noreferrer");
}
// set non-HTML/MathML links to xlink:show=new
if (
!node.hasAttribute("target") &&
(node.hasAttribute("xlink:href") || node.hasAttribute("href"))
) {
node.setAttribute("xlink:show", "new");
}
});
},
beforeDestroy() {
DOMPurify.removeAllHooks();
props: {
value: { type: String, default: "" },
ayaType: { type: Number, default: null },
ayaId: { type: Number, default: null },
readonly: Boolean
},
data() {
return {
@@ -395,21 +379,37 @@ export default {
uploadFiles: [] //attachment upload files
};
},
props: {
value: { type: String, default: "" },
ayaType: { type: Number, default: null },
ayaId: { type: Number, default: null },
readonly: Boolean
computed: {
isEmpty() {
return this.value == null;
}
},
watch: {
value(value) {
this.localVal = value ?? "";
}
},
computed: {
isEmpty() {
return this.value == null;
}
created() {
// Add a hook to make all links open a new window
//https://github.com/cure53/DOMPurify/blob/master/demos/hooks-target-blank-demo.html
DOMPurify.addHook("afterSanitizeAttributes", function(node) {
// set all elements owning target to target=_blank
if ("target" in node) {
node.setAttribute("target", "_blank");
// prevent https://www.owasp.org/index.php/Reverse_Tabnabbing
node.setAttribute("rel", "noopener noreferrer");
}
// set non-HTML/MathML links to xlink:show=new
if (
!node.hasAttribute("target") &&
(node.hasAttribute("xlink:href") || node.hasAttribute("href"))
) {
node.setAttribute("xlink:show", "new");
}
});
},
beforeDestroy() {
DOMPurify.removeAllHooks();
},
methods: {
goHelp() {
@@ -542,7 +542,7 @@ export default {
//emit input event to parent form for dirty tracking
this.handleInput(this.localVal);
},
handleDoubleClick(i) {
handleDoubleClick() {
//the purpose of this is only to change the selection if it's got an extra space to the right
//because double clicking on a word with another word after it causes the space to be included
this.getSelectedRange();
@@ -929,10 +929,10 @@ export default {
},
onDrop(ev) {
//Drop image file
var files = Array.from(ev.dataTransfer.files);
let files = Array.from(ev.dataTransfer.files);
if (files.length > 0) {
//handle file drop
var files = Array.from(ev.dataTransfer.files);
files = Array.from(ev.dataTransfer.files);
if (files.length > 0) {
this.uploadFiles = files;
this.upload();

View File

@@ -8,8 +8,8 @@
<v-btn
icon
class="ml-n1 mr-2"
@click="openDialog = true"
:data-cy="`${dataCy}:open`"
@click="openDialog = true"
>
<v-icon>$ayiEdit</v-icon>
</v-btn>
@@ -25,7 +25,7 @@
<v-card-text>
<v-row>
<v-col cols="12">
<v-menu offset-y v-if="!readonly">
<v-menu v-if="!readonly" offset-y>
<template v-slot:activator="{ on, attrs }">
<span class="text-h6">
{{ $ay.t("AddressTypePhysical") }}</span
@@ -66,7 +66,7 @@
</v-list-item>
</v-list>
</v-menu>
<span class="text-h6" v-else>
<span v-else class="text-h6">
{{ $ay.t("AddressTypePhysical") }}</span
>
</v-col>
@@ -78,10 +78,10 @@
xl="3"
>
<v-text-field
ref="address"
v-model="value.address"
:readonly="readonly"
:label="$ay.t('AddressDeliveryAddress')"
ref="address"
data-cy="address"
:error-messages="form().serverErrors(this, 'address')"
@input="fieldValueChanged('address')"
@@ -96,10 +96,10 @@
xl="3"
>
<v-text-field
ref="city"
v-model="value.city"
:readonly="readonly"
:label="$ay.t('AddressCity')"
ref="city"
data-cy="city"
:error-messages="form().serverErrors(this, 'city')"
@input="fieldValueChanged('city')"
@@ -114,10 +114,10 @@
xl="3"
>
<v-text-field
ref="region"
v-model="value.region"
:readonly="readonly"
:label="$ay.t('AddressStateProv')"
ref="region"
data-cy="region"
:error-messages="form().serverErrors(this, 'region')"
@input="fieldValueChanged('region')"
@@ -132,10 +132,10 @@
xl="3"
>
<v-text-field
ref="country"
v-model="value.country"
:readonly="readonly"
:label="$ay.t('AddressCountry')"
ref="country"
data-cy="country"
:error-messages="form().serverErrors(this, 'country')"
@input="fieldValueChanged('country')"
@@ -150,15 +150,15 @@
xl="3"
>
<gz-decimal
ref="latitude"
v-model="value.latitude"
:readonly="readonly"
:label="$ay.t('AddressLatitude')"
ref="latitude"
data-cy="latitude"
:rules="[form().decimalValid(this, 'latitude')]"
:error-messages="form().serverErrors(this, 'latitude')"
@input="fieldValueChanged('latitude')"
:precision="6"
@input="fieldValueChanged('latitude')"
></gz-decimal>
</v-col>
@@ -170,20 +170,20 @@
xl="3"
>
<gz-decimal
ref="longitude"
v-model="value.longitude"
:readonly="readonly"
:label="$ay.t('AddressLongitude')"
ref="longitude"
data-cy="longitude"
:rules="[form().decimalValid(this, 'longitude')]"
:error-messages="form().serverErrors(this, 'longitude')"
@input="fieldValueChanged('longitude')"
:precision="6"
@input="fieldValueChanged('longitude')"
></gz-decimal>
</v-col>
<v-col cols="12">
<v-menu offset-y v-if="!readonly">
<v-menu v-if="!readonly" offset-y>
<template v-slot:activator="{ on, attrs }">
<span class="text-h6">
{{ $ay.t("AddressTypePostal") }}</span
@@ -216,7 +216,7 @@
</v-list-item>
</v-list>
</v-menu>
<span class="text-h6" v-else>
<span v-else class="text-h6">
{{ $ay.t("AddressTypePostal") }}</span
>
</v-col>
@@ -229,10 +229,10 @@
xl="3"
>
<v-text-field
ref="postAddress"
v-model="value.postAddress"
:readonly="readonly"
:label="$ay.t('AddressPostalDeliveryAddress')"
ref="postAddress"
data-cy="postAddress"
:error-messages="form().serverErrors(this, 'postAddress')"
@input="fieldValueChanged('postAddress')"
@@ -247,10 +247,10 @@
xl="3"
>
<v-text-field
ref="postCity"
v-model="value.postCity"
:readonly="readonly"
:label="$ay.t('AddressPostalCity')"
ref="postCity"
data-cy="postCity"
:error-messages="form().serverErrors(this, 'postCity')"
@input="fieldValueChanged('postCity')"
@@ -265,10 +265,10 @@
xl="3"
>
<v-text-field
ref="postRegion"
v-model="value.postRegion"
:readonly="readonly"
:label="$ay.t('AddressPostalStateProv')"
ref="postRegion"
data-cy="postRegion"
:error-messages="form().serverErrors(this, 'postRegion')"
@input="fieldValueChanged('postRegion')"
@@ -283,10 +283,10 @@
xl="3"
>
<v-text-field
ref="postCountry"
v-model="value.postCountry"
:readonly="readonly"
:label="$ay.t('AddressPostalCountry')"
ref="postCountry"
data-cy="postCountry"
:error-messages="form().serverErrors(this, 'postCountry')"
@input="fieldValueChanged('postCountry')"
@@ -301,10 +301,10 @@
xl="3"
>
<v-text-field
ref="postCode"
v-model="value.postCode"
:readonly="readonly"
:label="$ay.t('AddressPostalPostal')"
ref="postCode"
data-cy="postCode"
:error-messages="form().serverErrors(this, 'postCode')"
@input="fieldValueChanged('postCode')"
@@ -318,15 +318,15 @@
<v-btn
color="blue darken-1"
text
@click="close()"
:data-cy="`${dataCy}:btnok`"
@click="close()"
>{{ $ay.t("OK") }}</v-btn
>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
<v-dialog max-width="600px" v-model="openSelectDialog">
<v-dialog v-model="openSelectDialog" max-width="600px">
<v-card>
<v-card-title>
<span class="text-h5">{{ $ay.t("SelectAlternateAddress") }}</span>
@@ -361,14 +361,6 @@
</template>
<script>
export default {
data() {
return {
openDialog: false,
openSelectDialog: false,
selectType: 1,
alternateAddresses: []
};
},
props: {
value: {
default: null,
@@ -383,6 +375,25 @@ export default {
readonly: Boolean,
disabled: Boolean
},
data() {
return {
openDialog: false,
openSelectDialog: false,
selectType: 1,
alternateAddresses: []
};
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
displayServiceAddress() {
return formatAddress(this.value).physical;
}
},
methods: {
close() {
@@ -525,17 +536,6 @@ export default {
//could fail on some platforms
}
}
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
displayServiceAddress() {
return formatAddress(this.value).physical;
}
}
};

View File

@@ -2,17 +2,17 @@
<div>
<v-row>
<v-col
v-if="value.serial != 0 && canEditSerial"
cols="12"
sm="6"
lg="4"
xl="3"
v-if="value.serial != 0 && canEditSerial"
>
<v-text-field
ref="serial"
v-model="value.serial"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderSerialNumber')"
ref="serial"
data-cy="serial"
:rules="[
form().integerValid(this, 'serial'),
@@ -24,13 +24,13 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="customerId"
v-model="value.customerId"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.customerId"
:readonly="formState.readOnly || value.userIsRestrictedType"
:label="$ay.t('Customer')"
:can-clear="false"
ref="customerId"
data-cy="customerId"
:rules="[form().required(this, 'customerId')]"
:error-messages="form().serverErrors(this, 'customerId')"
@@ -135,14 +135,14 @@
cols="12"
>
<v-textarea
ref="notes"
v-model="value.notes"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderSummary')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
@@ -160,10 +160,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderCloseByDate')"
v-model="value.completeByDate"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="completeByDate"
v-model="value.completeByDate"
:label="$ay.t('WorkOrderCloseByDate')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="completeByDate"
:error-messages="form().serverErrors(this, 'completeByDate')"
@input="fieldValueChanged('completeByDate')"
@@ -184,12 +184,12 @@
xl="3"
>
<gz-pick-list
ref="contractId"
v-model="value.contractId"
:aya-type="$ay.ayt().Contract"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.contractId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Contract')"
ref="contractId"
data-cy="contractId"
:error-messages="form().serverErrors(this, 'contractId')"
@input="fieldValueChanged('contractId')"
@@ -210,12 +210,12 @@
xl="3"
>
<gz-pick-list
ref="projectId"
v-model="value.projectId"
:aya-type="$ay.ayt().Project"
:show-edit-icon="!value.userIsRestrictedType"
v-model="value.projectId"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('Project')"
ref="projectId"
data-cy="projectId"
:error-messages="form().serverErrors(this, 'projectId')"
@input="fieldValueChanged('projectId')"
@@ -236,10 +236,10 @@
xl="3"
>
<v-text-field
ref="invoiceNumber"
v-model="value.invoiceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderInvoiceNumber')"
ref="invoiceNumber"
data-cy="invoiceNumber"
:error-messages="form().serverErrors(this, 'invoiceNumber')"
@input="fieldValueChanged('invoiceNumber')"
@@ -260,10 +260,10 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderServiceDate')"
v-model="value.serviceDate"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="serviceDate"
v-model="value.serviceDate"
:label="$ay.t('WorkOrderServiceDate')"
:readonly="formState.readOnly || value.userIsTechRestricted"
data-cy="serviceDate"
:error-messages="form().serverErrors(this, 'serviceDate')"
@input="fieldValueChanged('serviceDate')"
@@ -278,6 +278,7 @@
xl="3"
>
<v-text-field
ref="customerContactName"
v-model="value.customerContactName"
:readonly="
formState.readOnly ||
@@ -286,7 +287,6 @@
value.userIsSubContractorRestricted
"
:label="$ay.t('WorkOrderCustomerContactName')"
ref="customerContactName"
data-cy="customerContactName"
:error-messages="form().serverErrors(this, 'customerContactName')"
@input="fieldValueChanged('customerContactName')"
@@ -307,10 +307,10 @@
xl="3"
>
<v-text-field
ref="customerReferenceNumber"
v-model="value.customerReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderCustomerReferenceNumber')"
ref="customerReferenceNumber"
data-cy="customerReferenceNumber"
:error-messages="form().serverErrors(this, 'customerReferenceNumber')"
@input="fieldValueChanged('customerReferenceNumber')"
@@ -331,10 +331,10 @@
xl="3"
>
<v-text-field
ref="internalReferenceNumber"
v-model="value.internalReferenceNumber"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderInternalReferenceNumber')"
ref="internalReferenceNumber"
data-cy="internalReferenceNumber"
:error-messages="form().serverErrors(this, 'internalReferenceNumber')"
@input="fieldValueChanged('internalReferenceNumber')"
@@ -355,10 +355,10 @@
xl="3"
>
<v-checkbox
ref="onsite"
v-model="value.onsite"
:readonly="formState.readOnly || value.userIsTechRestricted"
:label="$ay.t('WorkOrderOnsite')"
ref="onsite"
data-cy="onsite"
:error-messages="form().serverErrors(this, 'onsite')"
@change="fieldValueChanged('onsite')"
@@ -376,9 +376,9 @@
cols="12"
>
<gz-tag-picker
ref="tags"
v-model="value.tags"
:readonly="formState.readOnly || value.userIsTechRestricted"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -394,12 +394,12 @@
cols="12"
>
<gz-custom-fields
ref="customFields"
v-model="value.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly || value.userIsTechRestricted"
:parent-v-m="this"
key-start-with="WorkOrderCustom"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -417,13 +417,13 @@
cols="12"
>
<gz-wiki
:aya-type="pvm.ayaType"
:aya-id="value.id"
ref="wiki"
v-model="value.wiki"
:aya-type="pvm.ayaType"
:aya-id="value.id"
:readonly="formState.readOnly || value.userIsTechRestricted"
@input="fieldValueChanged('wiki')"
data-cy="wiki"
@input="fieldValueChanged('wiki')"
></gz-wiki
></v-col>
@@ -458,13 +458,6 @@ export default {
GzWoAddress,
GzWoSignature
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
props: {
value: {
@@ -476,6 +469,21 @@ export default {
type: Object
}
},
data() {
return {
canEditSerial: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull
])
};
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
},
methods: {
form() {
return window.$gz.form;
@@ -486,14 +494,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.reimburseUser`]="{ item }">
<v-simple-checkbox
@@ -86,8 +86,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -100,27 +100,27 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].name
"
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseName')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
"
:error-messages="
form().serverErrors(
this,
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
)
"
data-cy="expenses.name"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
)
"
data-cy="expenses.name"
></v-text-field>
</v-col>
@@ -132,15 +132,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].totalCost
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTotalCost')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
"
data-cy="expenses.totalCost"
:error-messages="
form().serverErrors(
@@ -177,6 +177,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeAmount
@@ -184,9 +187,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeAmount')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
"
data-cy="expenses.chargeAmount"
:error-messages="
form().serverErrors(
@@ -223,6 +223,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeToCustomer
@@ -230,9 +233,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeToCustomer')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
"
data-cy="expenses.chargeToCustomer"
:error-messages="
form().serverErrors(
@@ -256,15 +256,15 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].taxPaid
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseTaxPaid')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
"
data-cy="expenses.taxPaid"
:error-messages="
form().serverErrors(
@@ -301,18 +301,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.chargeTaxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseChargeTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
"
data-cy="expenses.chargeTaxCode"
:error-messages="
form().serverErrors(
@@ -340,6 +340,9 @@
xl="3"
>
<v-checkbox
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.reimburseUser
@@ -347,9 +350,6 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseReimburseUser')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
"
data-cy="expenses.reimburseUser"
:error-messages="
form().serverErrors(
@@ -373,20 +373,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemExpenseUserID')"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
"
data-cy="expenses.user"
:error-messages="
form().serverErrors(
@@ -408,6 +408,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].expenses[activeItemIndex]
.description
@@ -421,16 +424,13 @@
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
:ref="
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
"
data-cy="expenses.description"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -439,15 +439,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -466,144 +457,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -781,6 +639,148 @@ export default {
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.expensetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].userViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
//#################################### IMPORTANT ##################################################
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
//so that they are in agreement otherwise restricted users will never be able to create new records
this.value.items[this.activeWoItemIndex].expenses.push({
id: 0,
concurrency: 0,
description: null,
name: null,
totalCost: 0,
chargeAmount: 0,
taxPaid: 0,
chargeTaxCodeId: null,
taxCodeViz: null,
reimburseUser: false,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
chargeToCustomer: false,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now() //used for error tracking / display
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].expenses.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.hasData &&
this.value.items[this.activeWoItemIndex].expenses.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].expenses[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].expenses[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
}
};
</script>

View File

@@ -58,10 +58,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -70,9 +70,9 @@
data-cy="laborsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -82,8 +82,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -96,16 +96,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStartDate
"
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
"
data-cy="serviceStartDate"
:error-messages="
form().serverErrors(
@@ -129,16 +129,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceStopDate
"
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
"
data-cy="serviceStopDate"
:rules="[
form().datePrecedence(
@@ -169,6 +169,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateQuantity
@@ -176,9 +179,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
"
data-cy="laborServiceRateQuantity"
:error-messages="
form().serverErrors(
@@ -212,19 +212,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
"
data-cy="labors.serviceRateId"
:error-messages="
form().serverErrors(
@@ -249,20 +249,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborUserID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
"
data-cy="labors.userid"
:error-messages="
form().serverErrors(
@@ -287,6 +287,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.noChargeQuantity
@@ -294,9 +297,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
"
data-cy="laborNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -333,18 +333,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLaborTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
"
data-cy="laborTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -372,6 +372,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.priceOverride
@@ -380,9 +383,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
"
data-cy="laborpriceoverride"
:error-messages="
form().serverErrors(
@@ -409,6 +409,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
v-model="
value.items[activeWoItemIndex].labors[activeItemIndex]
.serviceDetails
@@ -422,16 +425,13 @@
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
"
data-cy="laborserviceDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -440,15 +440,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -467,238 +458,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -985,6 +749,242 @@ export default {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.labortopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
appendTasks() {
const tasks = this.value.items[this.activeWoItemIndex].tasks;
if (tasks.length == 0) {
return;
}
const l = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
];
let at = "";
tasks.forEach(z => {
at += `${z.task} - ${z.statusViz}\n`;
});
l.serviceDetails += `\n${at}`;
},
userChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].labors.length;
this.value.items[this.activeWoItemIndex].labors.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
serviceStartDate: null,
serviceStopDate: null,
serviceRateId: null,
serviceDetails: null,
serviceRateQuantity: 0,
noChargeQuantity: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
serviceRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].labors.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate;
const dStop = this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate;
if (ref.includes("serviceStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("serviceStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].labors[
this.activeItemIndex
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -50,10 +50,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -62,9 +62,9 @@
data-cy="loansTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -74,8 +74,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -88,23 +88,23 @@
xl="3"
>
<gz-pick-list
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
"
:aya-type="$ay.ayt().LoanUnit"
:variant="
'availableonly:' +
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
"
:show-edit-icon="!value.userIsRestrictedType"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanUnit')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
"
data-cy="loans.loanUnitId"
:rules="[
form().required(
@@ -138,6 +138,7 @@
xl="3"
>
<v-select
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
v-model="value.items[activeWoItemIndex].loans[activeItemIndex].rate"
:items="pvm.selectLists.loanUnitRateUnits"
item-text="name"
@@ -145,7 +146,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanRate')"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
data-cy="loans.rate"
:error-messages="
form().serverErrors(
@@ -173,15 +173,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].quantity
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanQuantity')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
"
data-cy="loans.quantity"
:error-messages="
form().serverErrors(
@@ -215,15 +215,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanOutDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
"
:label="$ay.t('WorkOrderItemLoanOutDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loans.loaned"
:error-messages="
form().serverErrors(
@@ -247,15 +247,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanDueDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
"
:label="$ay.t('WorkOrderItemLoanDueDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loans.due"
:error-messages="
form().serverErrors(
@@ -279,15 +279,15 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemLoanReturnDate')"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
"
:label="$ay.t('WorkOrderItemLoanReturnDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
data-cy="loans.returned"
:error-messages="
form().serverErrors(
@@ -314,17 +314,17 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
data-cy="loans.taxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -352,6 +352,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex]
.priceOverride
@@ -360,9 +363,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
"
data-cy="loans.priceoverride"
:error-messages="
form().serverErrors(
@@ -386,6 +386,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemLoanNotes')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].loans[activeItemIndex].notes
"
@@ -398,14 +399,13 @@
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
data-cy="loans.notes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -414,15 +414,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -441,151 +432,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -876,6 +727,155 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.loantopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
loanUnitRateUnitChange(newId) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
s => s.id == newId
).name;
},
loanUnitChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].loans.length;
this.value.items[this.activeWoItemIndex].loans.push({
id: 0,
concurrency: 0,
notes: null,
outDate: null,
dueDate: null,
returnDate: null,
taxCodeId: window.$gz.store.state.globalSettings.defaultTaxPartSaleId,
loanUnitId: 0, //zero to break rule on new
quantity: 1,
rate: 1,
cost: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
loanUnitViz: null,
taxCodeViz: null,
unitOfMeasureViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].loanUnitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].loans.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].loans[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="outsideServicesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,18 +87,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.unitId
"
:aya-type="$ay.ayt().Unit"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].unitId`
"
data-cy="outsideServices.unitId"
:rules="[
form().required(
@@ -131,18 +131,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentToId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentToID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentToId`
"
data-cy="outsideServices.vendorSentToId"
:error-messages="
form().serverErrors(
@@ -167,6 +167,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.rmaNumber
@@ -174,21 +177,18 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRMANumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
"
:error-messages="
form().serverErrors(
this,
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
)
"
data-cy="outsideServices.rma"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].rmaNumber`
)
"
data-cy="outsideServices.rma"
></v-text-field>
</v-col>
<v-col
@@ -199,6 +199,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairCost
@@ -207,9 +210,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairCost`
"
data-cy="outsideServices.repairCost"
:error-messages="
form().serverErrors(
@@ -239,6 +239,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.repairPrice
@@ -247,9 +250,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceRepairPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].repairPrice`
"
data-cy="outsideServices.repairPrice"
:error-messages="
form().serverErrors(
@@ -281,18 +281,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.vendorSentViaId
"
:aya-type="$ay.ayt().Vendor"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceVendorSentViaID')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].vendorSentViaId`
"
data-cy="outsideServices.vendorSentViaId"
:error-messages="
form().serverErrors(
@@ -319,6 +319,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.trackingNumber
@@ -326,21 +329,18 @@
:readonly="formState.readOnly"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceTrackingNumber')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
"
:error-messages="
form().serverErrors(
this,
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
)
"
data-cy="outsideServices.trackingNumber"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].trackingNumber`
)
"
data-cy="outsideServices.trackingNumber"
></v-text-field>
</v-col>
<v-col
@@ -351,6 +351,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingCost
@@ -359,9 +362,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingCost')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingCost`
"
data-cy="outsideServices.shippingCost"
:error-messages="
form().serverErrors(
@@ -391,6 +391,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.shippingPrice
@@ -399,9 +402,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemOutsideServiceShippingPrice')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].shippingPrice`
"
data-cy="outsideServices.shippingPrice"
:error-messages="
form().serverErrors(
@@ -431,16 +431,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.sentDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateSent')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].sentDate`
"
data-cy="outsideServices.sentDate"
:error-messages="
form().serverErrors(
@@ -464,16 +464,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.etaDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateETA')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].etaDate`
"
data-cy="outsideServices.etaDate"
:error-messages="
form().serverErrors(
@@ -497,16 +497,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.returnDate
"
:label="$ay.t('WorkOrderItemOutsideServiceDateReturned')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].returnDate`
"
data-cy="outsideServices.returnDate"
:error-messages="
form().serverErrors(
@@ -530,18 +530,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.taxCodeId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('TaxCode')"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].taxCodeId`
"
data-cy="outsideServices.taxCodeId"
:error-messages="
form().serverErrors(
@@ -563,6 +563,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
v-model="
value.items[activeWoItemIndex].outsideServices[activeItemIndex]
.notes
@@ -576,16 +579,13 @@
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
:ref="
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
"
data-cy="outsideServices.notes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].outsideServices[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -594,15 +594,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -621,162 +612,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null, //Is it labor or parts tax code? wasn't in v7 leaving empty for now
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1087,6 +927,166 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.outsideservicetopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
unitChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitViz = newName;
},
vendorSentToChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentToViz = newName;
},
vendorSentViaChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].vendorSentViaViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].outsideServices
.length;
this.value.items[this.activeWoItemIndex].outsideServices.push({
id: 0,
concurrency: 0,
unitId: 0, //zero to break rule on new
notes: null,
vendorSentToId: null,
vendorSentViaId: null,
rmaNumber: null,
trackingNumber: null,
repairCost: 0,
repairPrice: 0,
shippingCost: 0,
shippingPrice: 0,
sentDate: window.$gz.locale.nowUTC8601String(),
etaDate: null,
returnDate: null,
taxCodeId: null, //Is it labor or parts tax code? wasn't in v7 leaving empty for now
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
unitViz: null,
vendorSentToViz: null,
vendorSentViaViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
//trigger rule breaking / validation
this.$nextTick(() => {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].unitId = null;
this.fieldValueChanged(
`Items[${this.activeWoItemIndex}].outsideServices[${this.activeItemIndex}].unitId`
);
});
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].outsideServices.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (
this.value.items[this.activeWoItemIndex].outsideServices.length == 1
) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].outsideServices[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].outsideServices[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].OutsideServices[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -44,10 +44,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -56,9 +56,9 @@
data-cy="partRequestsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
<template v-slot:[`item.purchaseOrderOnOrderViz`]="{ item }">
<v-simple-checkbox
@@ -79,8 +79,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -90,15 +90,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -117,95 +108,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
this.selectedRow = [{ index: val }];
this.activeItemIndex = val;
this.$nextTick(() => {
const el = this.$refs.partrequesttopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
openPO(item) {
if (
item != null &&
item.purchaseOrderIdViz != null &&
item.purchaseOrderIdViz != 0
) {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.PurchaseOrder,
id: item.purchaseOrderIdViz
});
}
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].partRequests[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].partRequests[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].partRequests.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].partRequests.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].partRequests[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].PartRequests[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -386,6 +293,99 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
this.selectedRow = [{ index: val }];
this.activeItemIndex = val;
this.$nextTick(() => {
const el = this.$refs.partrequesttopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
openPO(item) {
if (
item != null &&
item.purchaseOrderIdViz != null &&
item.purchaseOrderIdViz != 0
) {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.PurchaseOrder,
id: item.purchaseOrderIdViz
});
}
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].partRequests[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].partRequests[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].partRequests.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].partRequests.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].partRequests[item.index]
.deleted === true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].PartRequests[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -14,8 +14,8 @@
large
icon
v-bind="attrs"
v-on="on"
data-cy="woItemPartsHeader"
v-on="on"
>
<v-icon small color="primary">$ayiEllipsisV</v-icon>
</v-btn>
@@ -41,8 +41,8 @@
</v-list-item>
<v-list-item
v-if="canAdd"
@click="partAssemblyDialog = true"
data-cy="woItemPartAssemblySelect"
@click="partAssemblyDialog = true"
>
<v-list-item-icon>
<v-icon>$ayiObjectGroup</v-icon>
@@ -77,10 +77,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -89,9 +89,9 @@
data-cy="partsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -101,8 +101,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -115,19 +115,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].partId
"
:aya-type="$ay.ayt().Part"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partId`
"
data-cy="parts.partId"
:error-messages="
form().serverErrors(
@@ -162,18 +162,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.partWarehouseId
"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].partWarehouseId`
"
data-cy="parts.partWarehouseId"
:error-messages="
form().serverErrors(
@@ -197,6 +197,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].quantity
"
@@ -205,9 +208,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartQuantity')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].quantity`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -254,6 +254,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].suggestedQuantity`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.suggestedQuantity
@@ -263,9 +266,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartSuggestedQuantity')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].suggestedQuantity`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -295,6 +295,9 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].description
"
@@ -303,9 +306,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartDescription')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].description`
"
data-cy="partQuantity"
:error-messages="
form().serverErrors(
@@ -332,18 +332,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.taxPartSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemPartTaxPartSaleID')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].taxPartSaleId`
"
data-cy="partTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -371,6 +371,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex]
.priceOverride
@@ -379,9 +382,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].priceOverride`
"
data-cy="partpriceoverride"
:error-messages="
form().serverErrors(
@@ -405,6 +405,9 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemPartSerials')" cols="12">
<v-textarea
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
v-model="
value.items[activeWoItemIndex].parts[activeItemIndex].serials
"
@@ -417,17 +420,14 @@
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
:ref="
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
"
data-cy="partSerials"
auto-grow
prepend-icon="$ayiListUl"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].parts[${activeItemIndex}].serials`
)
"
auto-grow
prepend-icon="$ayiListUl"
@click:prepend="selectSerials()"
></v-textarea>
</v-col>
@@ -438,16 +438,16 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="partAssemblyDialog">
<v-dialog v-model="partAssemblyDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedPartAssembly"
v-model="selectedPartAssembly"
:aya-type="$ay.ayt().PartAssembly"
show-edit-icon
v-model="selectedPartAssembly"
:label="$ay.t('PartAssemblyList')"
ref="selectedPartAssembly"
data-cy="selectedPartAssembly"
></gz-pick-list>
@@ -456,16 +456,16 @@
pvm.useInventory &&
form().showMe(this, 'WorkOrderItemPartPartWarehouseID')
"
ref="selectedPartWarehouse"
v-model="selectedPartWarehouse"
:aya-type="$ay.ayt().PartWarehouse"
show-edit-icon
v-model="selectedPartWarehouse"
:label="$ay.t('WorkOrderItemPartPartWarehouseID')"
ref="selectedPartWarehouse"
data-cy="selectedPartWarehouse"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="partAssemblyDialog = false" color="primary">{{
<v-btn text color="primary" @click="partAssemblyDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -473,9 +473,9 @@
:disabled="selectedPartAssembly == null"
color="primary"
text
@click="addPartAssembly()"
class="ml-4"
data-cy="woItemPartAssemblyAdd"
@click="addPartAssembly()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -488,10 +488,10 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="serialDialog">
<v-dialog v-model="serialDialog" persistent max-width="600px">
<v-card>
<v-card-title>
<v-btn text @click="serialDialog = false" color="primary">{{
<v-btn text color="primary" @click="serialDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -519,21 +519,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
props: {
value: {
default: null,
@@ -552,6 +537,320 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
partAssemblyDialog: false,
selectedPartAssembly: null,
selectedPartWarehouse: 1,
serialDialog: false,
availableSerials: [],
selectedSerials: []
};
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSuggestedQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartSuggestedQuantity"),
align: "right",
value: "suggestedQuantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
suggestedQuantity: window.$gz.locale.decimalLocalized(
x.suggestedQuantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -576,6 +875,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
generateUnit() {
const thisPart = this.value.items[this.activeWoItemIndex].parts[
@@ -891,308 +1193,6 @@ export default {
return ret;
}
//---
},
computed: {
requestMore: function() {
return this.$ay
.t("WorkOrderItemPartRequestMore")
.replace(
"{n}",
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.requestAmountViz
);
},
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].parts[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemPartPartID")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartID"),
align: "left",
value: "partNameViz"
});
}
if (
this.pvm.useInventory &&
this.form().showMe(this, "WorkOrderItemPartPartWarehouseID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemPartPartWarehouseID"),
align: "left",
value: "partWarehouseViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartQuantity"),
align: "right",
value: "quantity"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSuggestedQuantity")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartSuggestedQuantity"),
align: "right",
value: "suggestedQuantity"
});
}
if (this.form().showMe(this, "PartDescription")) {
headers.push({
text: this.$ay.t("PartDescription"),
align: "left",
value: "partDescriptionViz"
});
}
if (this.form().showMe(this, "PartUPC")) {
headers.push({
text: this.$ay.t("PartUPC"),
align: "left",
value: "upcViz"
});
}
if (this.form().showMe(this, "WorkOrderItemPartDescription")) {
headers.push({
text: this.$ay.t("WorkOrderItemPartDescription"),
align: "left",
value: "description"
});
}
if (this.form().showMe(this, "WorkOrderItemPartSerials")) {
headers.push({
text: this.$ay.t("PurchaseOrderItemSerialNumbers"),
align: "left",
value: "serials"
});
}
if (this.form().showMe(this, "PartUnitOfMeasureViz")) {
headers.push({
text: this.$ay.t("UnitOfMeasure"),
align: "left",
value: "unitOfMeasureViz"
});
}
if (
this.form().showMe(this, "PartCost") &&
this.value.userCanViewPartCosts &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Cost"),
align: "right",
value: "cost"
});
}
if (
this.form().showMe(this, "PartListPrice") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("ListPrice"),
align: "right",
value: "listPrice"
});
}
if (
this.form().showMe(this, "PartPriceOverride") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("PriceOverride"),
align: "right",
value: "priceOverride"
});
}
if (
this.form().showMe(this, "PartPriceViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Price"),
align: "right",
value: "priceViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemPartTaxPartSaleID") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("Tax"),
align: "left",
value: "taxCodeViz"
});
}
if (
this.form().showMe(this, "PartNetViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("NetPrice"),
align: "right",
value: "netViz"
});
}
if (
this.form().showMe(this, "PartTaxAViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxAAmt"),
align: "right",
value: "taxAViz"
});
}
if (
this.form().showMe(this, "PartTaxBViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("TaxBAmt"),
align: "right",
value: "taxBViz"
});
}
if (
this.form().showMe(this, "PartLineTotalViz") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("LineTotal"),
align: "right",
value: "lineTotalViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].parts.map((x, i) => {
return {
index: i,
id: x.id,
partNameViz: x.partNameViz,
partWarehouseViz: x.partWarehouseViz,
quantity: window.$gz.locale.decimalLocalized(
x.quantity,
this.pvm.languageName
),
suggestedQuantity: window.$gz.locale.decimalLocalized(
x.suggestedQuantity,
this.pvm.languageName
),
partDescriptionViz: x.partDescriptionViz,
upcViz: x.upcViz,
description: x.description,
serials: window.$gz.util.truncateString(
x.serials,
this.pvm.maxTableNotesLength
),
unitOfMeasureViz: x.unitOfMeasureViz,
cost: window.$gz.locale.currencyLocalized(
x.cost,
this.pvm.languageName,
this.pvm.currencyName
),
listPrice: window.$gz.locale.currencyLocalized(
x.listPrice,
this.pvm.languageName,
this.pvm.currencyName
),
priceViz: window.$gz.locale.currencyLocalized(
x.priceViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxCodeViz: x.taxCodeViz,
priceOverride: window.$gz.locale.currencyLocalized(
x.priceOverride,
this.pvm.languageName,
this.pvm.currencyName
),
netViz: window.$gz.locale.currencyLocalized(
x.netViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxAViz: window.$gz.locale.currencyLocalized(
x.taxAViz,
this.pvm.languageName,
this.pvm.currencyName
),
taxBViz: window.$gz.locale.currencyLocalized(
x.taxBViz,
this.pvm.languageName,
this.pvm.currencyName
),
lineTotalViz: window.$gz.locale.currencyLocalized(
x.lineTotalViz,
this.pvm.languageName,
this.pvm.currencyName
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].parts.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
//----
}
};
</script>

View File

@@ -71,10 +71,10 @@
<!-- ################################ SCHEDULED USERS TABLE ############################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -83,9 +83,9 @@
data-cy="scheduledUsersTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -95,8 +95,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -109,16 +109,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.startDate
"
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
"
data-cy="startDate"
:error-messages="
form().serverErrors(
@@ -142,16 +142,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.stopDate
"
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
"
data-cy="stopDate"
:rules="[
form().datePrecedence(
@@ -184,6 +184,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.estimatedQuantity
@@ -193,9 +196,6 @@
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserEstimatedQuantity')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
"
data-cy="scheduledUsers.EstimatedQuantity"
:error-messages="
form().serverErrors(
@@ -229,21 +229,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserUserID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
"
data-cy="scheduledUsers.userid"
:error-messages="
form().serverErrors(
@@ -268,21 +268,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
v-model="
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
.serviceRateId
"
:aya-type="$ay.ayt().ServiceRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemScheduledUserServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
"
data-cy="scheduledUsers.serviceRateId"
:error-messages="
form().serverErrors(
@@ -304,15 +304,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -331,6 +322,136 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -355,6 +476,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
convertAllToLabor() {
this.value.items[this.activeWoItemIndex].scheduledUsers.forEach(z => {
@@ -574,130 +698,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
] == null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].scheduledUsers[
this.activeItemIndex
].deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
align: "right",
value: "startDate"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
align: "right",
value: "stopDate"
});
}
if (
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
align: "right",
value: "estimatedQuantity"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
align: "left",
value: "userViz"
});
}
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
headers.push({
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
align: "left",
value: "serviceRateViz"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
(x, i) => {
return {
index: i,
id: x.id,
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.startDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.stopDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
),
estimatedQuantity: window.$gz.locale.decimalLocalized(
x.estimatedQuantity,
this.pvm.languageName
),
userViz: x.userViz,
serviceRateViz: x.serviceRateViz
};
}
);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
hasMultipleItems: function() {
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
}
}
};
</script>

View File

@@ -14,8 +14,8 @@
large
icon
v-bind="attrs"
v-on="on"
data-cy="woItemTasksHeader"
v-on="on"
>
<v-icon small color="primary">$ayiEllipsisV</v-icon>
</v-btn>
@@ -30,8 +30,8 @@
</v-list-item>
<v-list-item
v-if="canAdd"
@click="taskGroupDialog = true"
data-cy="woItemTaskGroupSelect"
@click="taskGroupDialog = true"
>
<v-list-item-icon>
<v-icon>$ayiTasks</v-icon>
@@ -66,10 +66,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -78,9 +78,9 @@
data-cy="expensesTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -90,8 +90,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -104,15 +104,15 @@
xl="3"
>
<v-text-field
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].sequence
"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
:label="$ay.t('Sequence')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
"
:rules="[
form().integerValid(
this,
@@ -125,12 +125,12 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
)
"
type="number"
></v-text-field>
</v-col>
@@ -147,6 +147,9 @@
xl="3"
>
<v-select
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex].status
"
@@ -156,9 +159,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskWorkOrderItemTaskCompletionType')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
"
data-cy="usertype"
:rules="[
form().integerValid(
@@ -189,21 +189,21 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedByUserId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTaskUser')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
"
data-cy="expenseUser"
:error-messages="
form().serverErrors(
@@ -228,16 +228,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
v-model="
value.items[activeWoItemIndex].tasks[activeItemIndex]
.completedDate
"
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
"
data-cy="travelCompletedDate"
:error-messages="
form().serverErrors(
@@ -255,6 +255,7 @@
<v-col v-if="form().showMe(this, 'WorkOrderItemTaskTaskID')" cols="12">
<v-textarea
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
v-model="value.items[activeWoItemIndex].tasks[activeItemIndex].task"
:readonly="formState.readOnly || value.userIsRestrictedType"
:disabled="isDeleted"
@@ -271,14 +272,13 @@
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
]"
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
data-cy="task"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -288,21 +288,21 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog max-width="600px" v-model="taskGroupDialog">
<v-dialog v-model="taskGroupDialog" max-width="600px">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<gz-pick-list
ref="selectedTaskGroup"
v-model="selectedTaskGroup"
:aya-type="$ay.ayt().TaskGroup"
show-edit-icon
v-model="selectedTaskGroup"
:label="$ay.t('TaskGroupList')"
ref="selectedTaskGroup"
data-cy="selectedTaskGroup"
></gz-pick-list>
</v-card-text>
<v-card-actions>
<v-btn text @click="taskGroupDialog = false" color="primary">{{
<v-btn text color="primary" @click="taskGroupDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -310,9 +310,9 @@
:disabled="selectedTaskGroup == null"
color="primary"
text
@click="addTaskGroup()"
class="ml-4"
data-cy="woItemTaskGroupAdd"
@click="addTaskGroup()"
>{{ $ay.t("Add") }}</v-btn
>
</v-card-actions>
@@ -324,17 +324,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
props: {
value: {
default: null,
@@ -353,6 +342,127 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
taskGroupDialog: false,
selectedTaskGroup: null
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -377,6 +487,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
async addTaskGroup() {
const res = await window.$gz.api.get(
@@ -545,119 +658,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
headers.push({
text: this.$ay.t("Sequence"),
align: "left",
value: "sequence"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskTaskID"),
align: "start",
value: "task"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskUser"),
align: "start",
value: "completedByUserViz"
});
}
if (
this.form().showMe(
this,
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
)
) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
align: "start",
value: "statusViz"
});
}
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
headers.push({
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
align: "right",
value: "completedDate"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].tasks
.map((x, i) => {
return {
index: i,
id: x.id,
sequence: x.sequence,
task: x.task,
completedByUserViz: x.completedByUserViz,
statusViz: x.statusViz,
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
x.completedDate,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
)
};
})
.sort((a, b) => a.sequence - b.sequence);
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

View File

@@ -49,10 +49,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -61,9 +61,9 @@
data-cy="travelsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -73,8 +73,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -87,16 +87,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStartDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStartDate
"
:label="$ay.t('WorkOrderItemTravelStartDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
"
data-cy="travelStartDate"
:error-messages="
form().serverErrors(
@@ -120,16 +120,16 @@
xl="3"
>
<gz-date-time-picker
:label="$ay.t('WorkOrderItemTravelStopDate')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelStopDate
"
:label="$ay.t('WorkOrderItemTravelStopDate')"
:readonly="formState.readOnly"
:disabled="isDeleted"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
"
data-cy="travelStopDate"
:rules="[
form().datePrecedence(
@@ -160,6 +160,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateQuantity
@@ -167,9 +170,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelRateQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
"
data-cy="travelTravelRateQuantity"
:error-messages="
form().serverErrors(
@@ -203,15 +203,15 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].distance
"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelDistance')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].distance`
"
data-cy="travelTravelRateDistance"
:error-messages="
form().serverErrors(
@@ -245,19 +245,19 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelRateId
"
:aya-type="$ay.ayt().TravelRate"
:variant="'contractid:' + value.contractId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelServiceRateID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
"
data-cy="travels.travelRateId"
:error-messages="
form().serverErrors(
@@ -282,20 +282,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex].userId
"
:aya-type="$ay.ayt().User"
variant="tech"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelUserID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
"
data-cy="travels.userid"
:error-messages="
form().serverErrors(
@@ -320,6 +320,9 @@
xl="3"
>
<gz-decimal
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.noChargeQuantity
@@ -327,9 +330,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelNoChargeQuantity')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
"
data-cy="travelNoChargeQuantity"
:error-messages="
form().serverErrors(
@@ -366,18 +366,18 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.taxCodeSaleId
"
:aya-type="$ay.ayt().TaxCode"
show-edit-icon
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('WorkOrderItemTravelTaxRateSaleID')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
"
data-cy="travelTaxCodeSaleId"
:error-messages="
form().serverErrors(
@@ -405,6 +405,9 @@
xl="3"
>
<gz-currency
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.priceOverride
@@ -413,9 +416,6 @@
:readonly="formState.readOnly || isDeleted"
:disabled="isDeleted"
:label="$ay.t('PriceOverride')"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
"
data-cy="travelpriceoverride"
:error-messages="
form().serverErrors(
@@ -442,6 +442,9 @@
cols="12"
>
<v-textarea
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
v-model="
value.items[activeWoItemIndex].travels[activeItemIndex]
.travelDetails
@@ -455,16 +458,13 @@
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
:ref="
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
"
data-cy="traveltravelDetails"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
)
"
auto-grow
></v-textarea>
</v-col>
</template>
@@ -473,15 +473,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
props: {
value: {
default: null,
@@ -500,225 +491,11 @@ export default {
type: Number
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId: null,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
data() {
return {
activeItemIndex: null,
selectedRow: []
};
},
computed: {
isDeleted: function() {
@@ -1018,6 +795,229 @@ export default {
}
//----
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
this.setDefaultView();
}
},
gotoIndex(val, oldVal) {
if (val != oldVal) {
let gotoIndex = val;
if (val < 0) {
//it's a create request
gotoIndex = this.newItem();
}
this.selectedRow = [{ index: gotoIndex }];
this.activeItemIndex = gotoIndex;
this.$nextTick(() => {
const el = this.$refs.traveltopform;
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
});
}
}
},
created() {
this.setDefaultView();
},
methods: {
userChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].userViz = newName;
},
rateChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateViz = newName;
},
taxCodeChange(newName) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].taxCodeViz = newName;
},
newItem() {
const newIndex = this.value.items[this.activeWoItemIndex].travels.length;
this.value.items[this.activeWoItemIndex].travels.push({
id: 0,
concurrency: 0,
userId: this.$store.getters.isScheduleableUser
? this.$store.state.userId
: null,
travelStartDate: null,
travelStopDate: null,
travelRateId: null,
travelDetails: null,
travelRateQuantity: 0,
noChargeQuantity: 0,
distance: 0,
taxCodeSaleId:
window.$gz.store.state.globalSettings.defaultTaxRateSaleId,
price: 0,
priceOverride: null,
isDirty: true,
workOrderItemId: this.value.items[this.activeWoItemIndex].id,
uid: Date.now(),
userViz: this.$store.getters.isScheduleableUser
? this.$store.state.userName
: null,
travelRateViz: null,
taxCodeViz: null
});
this.$emit("change");
this.selectedRow = [{ index: newIndex }];
this.activeItemIndex = newIndex;
return newIndex; //for create new on goto
},
unDeleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = false;
this.setDefaultView();
},
deleteItem() {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].deleted = true;
this.setDefaultView();
this.$emit("change");
},
deleteAllItem() {
this.value.items[this.activeWoItemIndex].travels.forEach(
z => (z.deleted = true)
);
this.setDefaultView();
this.$emit("change");
},
setDefaultView: function() {
//if only one record left then display it otherwise just let the datatable show what the user can click on
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
this.selectedRow = [{ index: 0 }];
this.activeItemIndex = 0;
} else {
this.selectedRow = [];
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
}
},
handleRowClick: function(item) {
this.activeItemIndex = item.index;
this.selectedRow = [{ index: item.index }];
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (!this.formState.loading && !this.formState.readonly) {
//flag this record dirty so it gets picked up by save
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].isDirty = true;
window.$gz.form.fieldValueChanged(this.pvm, ref);
//------- SPECIAL HANDLING OF CHANGES -----------
const isNew =
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
.id == 0;
//Auto calculate dates / quantities / global defaults
const dStart = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate;
const dStop = this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate;
if (ref.includes("travelStartDate") && dStart != null) {
this.handleStartDateChange(isNew, dStart, dStop);
}
if (ref.includes("travelStopDate") && dStop != null) {
this.handleStopDateChange(isNew, dStart, dStop);
}
//------------------------------------------------------
}
},
handleStartDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStop == null) {
if (globalMinutes != 0) {
//set stop date based on start date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
dStart,
globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStop != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
handleStopDateChange: function(isNew, dStart, dStop) {
const globalMinutes =
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
if (isNew && dStart == null) {
if (globalMinutes != 0) {
//set start date based on stop date and global minutes
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
dStop,
0 - globalMinutes
);
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = globalMinutes;
}
} else {
//Existing record or both dates filled, just update quantity
if (dStart != null) {
this.value.items[this.activeWoItemIndex].travels[
this.activeItemIndex
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
dStart,
dStop
);
}
}
},
itemRowClasses: function(item) {
let ret = "";
const isDeleted =
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
true;
const hasError = this.form().childRowHasError(
this,
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
);
if (isDeleted) {
ret += this.form().tableRowDeletedClass();
}
if (hasError) {
ret += this.form().tableRowErrorClass();
}
return ret;
}
//---
}
};
</script>

View File

@@ -57,10 +57,10 @@
<!-- ############################################################### -->
<v-col cols="12" class="mb-10">
<v-data-table
v-model="selectedRow"
:headers="headerList"
:items="itemList"
item-key="index"
v-model="selectedRow"
class="elevation-1"
disable-pagination
disable-filtering
@@ -69,9 +69,9 @@
data-cy="unitsTable"
dense
:item-class="itemRowClasses"
@click:row="handleRowClick"
:show-select="$vuetify.breakpoint.xs"
single-select
@click:row="handleRowClick"
>
</v-data-table>
</v-col>
@@ -81,8 +81,8 @@
<v-btn
v-if="canDelete && isDeleted"
large
@click="unDeleteItem"
color="primary"
@click="unDeleteItem"
>{{ $ay.t("Undelete")
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
>
@@ -94,20 +94,20 @@
xl="3"
>
<gz-pick-list
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].unitId
"
:aya-type="$ay.ayt().Unit"
:variant="'customerid:' + value.customerId"
:show-edit-icon="!value.userIsRestrictedType"
:readonly="
formState.readOnly || isDeleted || value.userIsRestrictedType
"
:disabled="isDeleted"
:label="$ay.t('Unit')"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
"
data-cy="units.unitId"
:rules="[
form().required(
@@ -160,8 +160,8 @@
<v-btn
color="primary"
text
@click="getWarrantyInfo"
data-cy="woItemUnitGetWarrantyInfo"
@click="getWarrantyInfo"
>{{ $ay.t("Search") }}</v-btn
>
</v-card-actions>
@@ -176,6 +176,7 @@
cols="12"
>
<v-textarea
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].notes
"
@@ -188,14 +189,13 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
data-cy="unitUnitNotes"
auto-grow
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
)
"
auto-grow
></v-textarea>
</v-col>
@@ -207,6 +207,7 @@
cols="12"
>
<gz-tag-picker
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].tags"
:readonly="formState.readOnly"
data-cy="unitTags"
@@ -216,7 +217,6 @@
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
)
"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
@input="
fieldValueChanged(
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
@@ -227,6 +227,9 @@
<v-col v-if="!value.userIsRestrictedType" cols="12">
<gz-custom-fields
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
v-model="
value.items[activeWoItemIndex].units[activeItemIndex].customFields
"
@@ -234,9 +237,6 @@
:readonly="formState.readOnly"
:parent-v-m="this"
key-start-with="WorkOrderItemUnitCustom"
:ref="
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
"
data-cy="unitCustomFields"
:error-messages="
form().serverErrors(
@@ -260,10 +260,10 @@
cols="12"
>
<gz-wiki
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].wiki`"
v-model="value.items[activeWoItemIndex].units[activeItemIndex].wiki"
:aya-type="$ay.ayt().WorkOrderItem"
:aya-id="value.id"
:readonly="formState.readOnly"
@input="
fieldValueChanged(
@@ -294,22 +294,22 @@
<!-- ################################################################################-->
<template>
<v-row justify="center">
<v-dialog persistent max-width="600px" v-model="bulkUnitsDialog">
<v-dialog v-model="bulkUnitsDialog" persistent max-width="600px">
<v-card>
<v-card-title>{{ $ay.t("AddMultipleUnits") }}</v-card-title>
<v-card-text>
<gz-tag-picker v-model="selectedBulkUnitTags"></gz-tag-picker>
<gz-pick-list
v-model="selectedBulkUnitCustomer"
:aya-type="$ay.ayt().Customer"
:show-edit-icon="false"
v-model="selectedBulkUnitCustomer"
:label="$ay.t('Customer')"
:can-clear="true"
></gz-pick-list>
<v-data-table
dense
v-model="selectedBulkUnits"
dense
:headers="bulkUnitTableHeaders"
:items="availableBulkUnits"
class="my-10"
@@ -322,7 +322,7 @@
</v-data-table>
</v-card-text>
<v-card-actions>
<v-btn text @click="bulkUnitsDialog = false" color="primary">{{
<v-btn text color="primary" @click="bulkUnitsDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-spacer></v-spacer>
@@ -349,21 +349,6 @@
</template>
<script>
export default {
created() {
this.setDefaultView();
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
props: {
value: {
default: null,
@@ -386,6 +371,126 @@ export default {
type: Number
}
},
data() {
return {
activeItemIndex: null,
selectedRow: [],
bulkUnitsDialog: false,
selectedBulkUnitCustomer: this.value.customerId,
availableBulkUnits: [],
selectedBulkUnits: [],
selectedBulkUnitTags: [],
bulkUnitTableHeaders: []
};
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
},
watch: {
activeWoItemIndex(val, oldVal) {
if (val != oldVal) {
@@ -410,6 +515,9 @@ export default {
}
}
},
created() {
this.setDefaultView();
},
methods: {
canOpenMeter: function() {
return (
@@ -728,114 +836,6 @@ export default {
}
return ret;
}
},
computed: {
isDeleted: function() {
if (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
null
) {
this.setDefaultView();
return true;
}
return (
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
.deleted === true
);
},
parentDeleted: function() {
return this.value.items[this.activeWoItemIndex].deleted === true;
},
headerList: function() {
const headers = [];
if (this.form().showMe(this, "WorkOrderItemUnit")) {
headers.push({
text: this.$ay.t("Unit"),
align: "left",
value: "unitViz"
});
}
if (this.form().showMe(this, "UnitModelName")) {
headers.push({
text: this.$ay.t("UnitModelName"),
align: "left",
value: "unitModelNameViz"
});
}
if (this.form().showMe(this, "UnitModelVendorID")) {
headers.push({
text: this.$ay.t("UnitModelVendorID"),
align: "left",
value: "unitModelVendorViz"
});
}
if (this.form().showMe(this, "UnitDescription")) {
headers.push({
text: this.$ay.t("UnitDescription"),
align: "left",
value: "unitDescriptionViz"
});
}
if (
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
!this.value.userIsRestrictedType
) {
headers.push({
text: this.$ay.t("WorkOrderItemUnitNotes"),
align: "left",
value: "notes"
});
}
return headers;
},
itemList: function() {
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
return {
index: i,
id: x.id,
unitViz: x.unitViz,
unitModelVendorViz: x.unitModelVendorViz,
unitModelNameViz: x.unitModelNameViz,
unitDescriptionViz: x.unitDescriptionViz,
notes: window.$gz.util.truncateString(
x.notes,
this.pvm.maxTableNotesLength
)
};
});
},
formState: function() {
return this.pvm.formState;
},
formCustomTemplateKey: function() {
return this.pvm.formCustomTemplateKey;
},
hasData: function() {
return this.value.items[this.activeWoItemIndex].units.length > 0;
},
hasSelection: function() {
return this.activeItemIndex != null;
},
canAdd: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
},
canDelete: function() {
return (
this.activeItemIndex != null &&
this.canDeleteAll &&
!this.value.userIsRestrictedType
);
},
canDeleteAll: function() {
return this.pvm.rights.change && !this.value.userIsRestrictedType;
}
}
};
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
<template>
<div class="mb-8 ml-3">
<div class="mb-2 ml-8">
<span class="text-caption" v-if="variant == 'customer'">{{
<span v-if="variant == 'customer'" class="text-caption">{{
$ay.t("CustomerSignature")
}}</span>
<span class="text-caption" v-else>{{ $ay.t("TechSignature") }}</span>
<span v-else class="text-caption">{{ $ay.t("TechSignature") }}</span>
</div>
<template>
@@ -26,22 +26,22 @@
<v-row justify="center">
<v-dialog
v-model="openDialog"
overlay-opacity="1"
overlay-color="primary"
v-model="openDialog"
max-width="600px"
>
<v-card>
<v-card-title>
<span class="text-h4" v-if="variant == 'customer'">{{
<span v-if="variant == 'customer'" class="text-h4">{{
$ay.t("CustomerSignature")
}}</span>
<span class="subtitle-4" v-else>{{ $ay.t("TechSignature") }}</span>
<span v-else class="subtitle-4">{{ $ay.t("TechSignature") }}</span>
</v-card-title>
<v-card-text>
<div class="mb-5">
<span class="text-h5"
>{{ $ay.t("WorkOrder") }}&nbsp;{{ this.value.serial }}</span
>{{ $ay.t("WorkOrder") }}&nbsp;{{ value.serial }}</span
>
</div>
@@ -52,8 +52,8 @@
}}</span>
</div>
<div
class="mb-5"
v-if="$store.state.globalSettings.signatureHeader"
class="mb-5"
>
<span class="subtitle-1">{{
$store.state.globalSettings.signatureHeader
@@ -106,8 +106,8 @@
{{ sigDateLocalized }}
<template v-if="variant == 'customer'">
<div
class="my-5"
v-if="$store.state.globalSettings.signatureFooter"
class="my-5"
>
<span class="subtitle-2">{{
$store.state.globalSettings.signatureFooter
@@ -117,10 +117,10 @@
<template>
<div class="mt-8">
<v-text-field
ref="sigName"
v-model="tempName"
:readonly="disabled || imgUrl != null"
:label="$ay.t('Name')"
ref="sigName"
data-cy="sigName"
></v-text-field>
</div>
@@ -142,8 +142,8 @@
v-if="imgUrl == null"
color="blue darken-1"
text
@click="save()"
data-cy="sigOK"
@click="save()"
>{{ $ay.t("OK") }}</v-btn
>
</v-card-actions>
@@ -158,19 +158,6 @@ export default {
components: {
vueSignature
},
data() {
return {
selectedStatus: null,
openDialog: false,
sigOption: {
penColor: "rgb(0, 0, 0)",
backgroundColor: "rgb(245,245,245)"
},
tempSig: null,
tempDate: null,
tempName: null
};
},
props: {
value: {
default: null,
@@ -188,6 +175,64 @@ export default {
readonly: Boolean,
disabled: Boolean
},
data() {
return {
selectedStatus: null,
openDialog: false,
sigOption: {
penColor: "rgb(0, 0, 0)",
backgroundColor: "rgb(245,245,245)"
},
tempSig: null,
tempDate: null,
tempName: null
};
},
computed: {
hasSignature: function() {
return this.imgUrl != null;
},
imgUrl: function() {
let sig = null;
if (this.variant == "customer") {
sig = this.value.customerSignature;
} else {
sig = this.value.techSignature;
}
if (sig != null && sig.length > 0 && sig.includes("svg")) {
return sig;
} else {
return null;
}
},
sigDate: function() {
if (this.variant == "customer") {
return this.value.customerSignatureCaptured;
} else {
return this.value.techSignatureCaptured;
}
},
sigName: function() {
if (this.variant == "customer") {
return this.value.customerSignatureName;
} else {
return this.value.techSignatureName;
}
},
sigDateLocalized: function() {
const sd = this.sigDate;
if (sd == null) {
return null;
} else {
return window.$gz.locale.utcDateToShortDateAndTimeLocalized(
sd,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
);
}
}
},
methods: {
showSign() {
if (this.readonly) return;
@@ -257,51 +302,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
hasSignature: function() {
return this.imgUrl != null;
},
imgUrl: function() {
let sig = null;
if (this.variant == "customer") {
sig = this.value.customerSignature;
} else {
sig = this.value.techSignature;
}
if (sig != null && sig.length > 0 && sig.includes("svg")) {
return sig;
} else {
return null;
}
},
sigDate: function() {
if (this.variant == "customer") {
return this.value.customerSignatureCaptured;
} else {
return this.value.techSignatureCaptured;
}
},
sigName: function() {
if (this.variant == "customer") {
return this.value.customerSignatureName;
} else {
return this.value.techSignatureName;
}
},
sigDateLocalized: function() {
const sd = this.sigDate;
if (sd == null) {
return null;
} else {
return window.$gz.locale.utcDateToShortDateAndTimeLocalized(
sd,
this.pvm.timeZoneName,
this.pvm.languageName,
this.pvm.hour12
);
}
}
}
};
</script>

View File

@@ -6,8 +6,8 @@
<template>
<div
class="mb-6 mb-sm-0"
@click="openDialog = true"
:data-cy="`${dataCy}:open`"
@click="openDialog = true"
>
<v-btn icon class="ml-n1 mr-2">
<v-icon>{{ openIcon() }}</v-icon>
@@ -15,10 +15,10 @@
<span class="text-h6">{{ pvm.currentState.name }}</span>
<v-icon :color="pvm.currentState.color" class="ml-4">$ayiFlag</v-icon>
<v-icon color="primary" v-if="pvm.currentState.locked" class="ml-4"
<v-icon v-if="pvm.currentState.locked" color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon color="primary" v-if="pvm.currentState.completed" class="ml-4"
<v-icon v-if="pvm.currentState.completed" color="primary" class="ml-4"
>$ayiCheckCircle</v-icon
>
</div>
@@ -37,10 +37,10 @@
<span class="ml-3">{{ item.user }}</span>
<span class="font-weight-bold ml-3">{{ item.name }}</span>
<v-icon small :color="item.color" class="ml-4">$ayiFlag</v-icon>
<v-icon small color="primary" v-if="item.locked" class="ml-4"
<v-icon v-if="item.locked" small color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon small color="primary" v-if="item.completed" class="ml-4"
<v-icon v-if="item.completed" small color="primary" class="ml-4"
>$ayiCheckCircle</v-icon
>
</div>
@@ -55,13 +55,13 @@
<v-icon small :color="item.color" class="ml-4"
>$ayiFlag</v-icon
>
<v-icon small color="primary" v-if="item.locked" class="ml-4"
<v-icon v-if="item.locked" small color="primary" class="ml-4"
>$ayiLock</v-icon
>
<v-icon
v-if="item.completed"
small
color="primary"
v-if="item.completed"
class="ml-4"
>$ayiCheckCircle</v-icon
>
@@ -78,8 +78,8 @@
dense
:label="$ay.t('NewStatus')"
prepend-icon="$ayiEdit"
@click:prepend="handleEditStateClick()"
:data-cy="`${dataCy}:picker`"
@click:prepend="handleEditStateClick()"
>
<template v-slot:item="data">
<v-list-item-avatar>
@@ -91,17 +91,17 @@
data.item.name
}}</span
><v-icon
v-if="data.item.locked"
small
color="disabled"
class="ml-2"
v-if="data.item.locked"
>$ayiLock</v-icon
>
<v-icon
v-if="data.item.completed"
color="disabled"
class="ml-1"
small
v-if="data.item.completed"
>$ayiCheckCircle</v-icon
></v-list-item-title
>
@@ -125,8 +125,8 @@
color="blue darken-1"
:disabled="selectedStatus == null"
text
@click="save()"
:data-cy="`${dataCy}:btnok`"
@click="save()"
>{{ $ay.t("OK") }}</v-btn
>
</v-card-actions>
@@ -137,13 +137,6 @@
</template>
<script>
export default {
data() {
return {
selectedStatus: null,
openDialog: false
};
},
props: {
value: {
default: null,
@@ -166,6 +159,48 @@ export default {
readonly: Boolean,
disabled: Boolean
},
data() {
return {
selectedStatus: null,
openDialog: false
};
},
computed: {
hasState() {
return this.value.states != null && this.value.states.length > 0;
},
stateDisplayList() {
const ret = [];
this.value.states.forEach(z => {
ret.push(this.getStateForDisplay(z));
});
return ret;
},
canAdd: function() {
//first check most obvious disqualifying properties
if (!this.pvm.rights.change) {
return false;
}
//not currently locked, user has rights to do it so allow it
if (!this.value.isLockedAtServer) {
return true;
}
//locked, confirm if user can change it
//if any role then no problem
//only thing left to check is if the current user can unlock this
//get remove roles required for current state
const cs = this.pvm.currentState;
if (cs.removeRoles == null || cs.removeRoles == 0) {
//no state set yet
return true;
}
//need to check the role here against current user roles to see if this is valid
if (window.$gz.role.hasRole(cs.removeRoles)) {
return true;
}
return false;
}
},
methods: {
addState() {
@@ -248,42 +283,6 @@ export default {
window.$gz.form.fieldValueChanged(this.pvm, ref);
}
}
},
computed: {
hasState() {
return this.value.states != null && this.value.states.length > 0;
},
stateDisplayList() {
const ret = [];
this.value.states.forEach(z => {
ret.push(this.getStateForDisplay(z));
});
return ret;
},
canAdd: function() {
//first check most obvious disqualifying properties
if (!this.pvm.rights.change) {
return false;
}
//not currently locked, user has rights to do it so allow it
if (!this.value.isLockedAtServer) {
return true;
}
//locked, confirm if user can change it
//if any role then no problem
//only thing left to check is if the current user can unlock this
//get remove roles required for current state
const cs = this.pvm.currentState;
if (cs.removeRoles == null || cs.removeRoles == 0) {
//no state set yet
return true;
}
//need to check the role here against current user roles to see if this is valid
if (window.$gz.role.hasRole(cs.removeRoles)) {
return true;
}
return false;
}
}
};
</script>

View File

@@ -1,5 +1,3 @@
/* Xeslint-disable */
//import "typeface-roboto/index.css";
import "fontsource-roboto/latin.css";
import "github-markdown-css";
import Vue from "vue";
@@ -106,20 +104,10 @@ window.$gz = {
Vue.config.errorHandler = errorHandler.handleVueError;
window.onerror = errorHandler.handleGeneralError;
// //unhandled rejection handler
//shouldn't need this
// window.addEventListener("unhandledrejection", function(event) {
// // the event object has two special properties:
// alert(event.promise); // [object Promise] - the promise that generated the error
// alert(event.reason); // Error: Whoops! - the unhandled error object
// });
//warnings, only occur by default in debug mode not production
Vue.config.warnHandler = errorHandler.handleVueWarning;
//added for vuetify 2.x to disable annoying prodution mode tip warning
//but commented out for now just to see what it looks like
Vue.config.productionTip = false;
//Vue.config.productionTip = false;
/////////////////////////////////////////////////////////////////
// AJAX LOADER INDICATOR

View File

@@ -4,22 +4,22 @@
<div v-if="formState.ready">
<gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
<v-form ref="form">
<div class="mb-6" v-if="obj.aType">
<div v-if="obj.aType" class="mb-6">
<v-icon large @click="navToTarget()">{{ iconForType }}</v-icon
><span class="text-h5" @click="navToTarget()"> {{ name }}</span>
</div>
<v-row>
<v-col cols="12">
<v-textarea
ref="name"
v-model="obj.name"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankDescription')"
:rules="[form().required(this, 'name')]"
:error-messages="form().serverErrors(this, 'name')"
ref="name"
data-cy="name"
@input="fieldValueChanged('name')"
auto-grow
@input="fieldValueChanged('name')"
></v-textarea>
</v-col>
@@ -31,10 +31,10 @@
xl="3"
>
<gz-currency
ref="currency"
v-model="obj.currency"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankCurrency')"
ref="currency"
data-cy="currency"
:rules="[
form().decimalValid(this, 'currency'),
@@ -53,10 +53,10 @@
xl="3"
>
<gz-decimal
ref="hours"
v-model="obj.hours"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankHours')"
ref="hours"
data-cy="hours"
:rules="[
form().decimalValid(this, 'hours'),
@@ -75,10 +75,10 @@
xl="3"
>
<gz-decimal
ref="incidents"
v-model="obj.incidents"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankIncidents')"
ref="incidents"
data-cy="incidents"
:rules="[
form().decimalValid(this, 'incidents'),
@@ -101,6 +101,70 @@ const FORM_KEY = "service-bank-edit";
const API_BASE_URL = "service-bank/";
const FORM_CUSTOM_TEMPLATE_KEY = "ServiceBank";
export default {
data() {
return {
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
obj: {
id: 0,
concurrency: 0,
name: null,
objectId: null,
aType: null,
sourceId: 0, //default for manual entries
sourceType: window.$gz.type.ServiceBank,
incidents: 0,
currency: 0,
hours: 0
},
formState: {
ready: false,
dirty: false,
valid: true,
readOnly: false,
loading: true,
errorBoxMessage: null,
appError: null,
serverError: {}
},
rights: window.$gz.role.defaultRightsObject(),
name: null
};
},
computed: {
iconForType() {
return window.$gz.util.iconForType(this.obj.aType);
}
},
watch: {
formState: {
handler: function(val) {
if (this.formState.loading) {
return;
}
if (val.dirty && val.valid && !val.readOnly) {
window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":save");
} else {
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
}
if (!val.dirty && val.valid && !val.readOnly) {
window.$gz.eventBus.$emit(
"menu-enable-item",
FORM_KEY + ":duplicate"
);
window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":new");
} else {
window.$gz.eventBus.$emit(
"menu-disable-item",
FORM_KEY + ":duplicate"
);
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":new");
}
},
deep: true
}
},
async created() {
const vm = this;
try {
@@ -170,70 +234,6 @@ export default {
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
obj: {
id: 0,
concurrency: 0,
name: null,
objectId: null,
aType: null,
sourceId: 0, //default for manual entries
sourceType: window.$gz.type.ServiceBank,
incidents: 0,
currency: 0,
hours: 0
},
formState: {
ready: false,
dirty: false,
valid: true,
readOnly: false,
loading: true,
errorBoxMessage: null,
appError: null,
serverError: {}
},
rights: window.$gz.role.defaultRightsObject(),
name: null
};
},
watch: {
formState: {
handler: function(val) {
if (this.formState.loading) {
return;
}
if (val.dirty && val.valid && !val.readOnly) {
window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":save");
} else {
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
}
if (!val.dirty && val.valid && !val.readOnly) {
window.$gz.eventBus.$emit(
"menu-enable-item",
FORM_KEY + ":duplicate"
);
window.$gz.eventBus.$emit("menu-enable-item", FORM_KEY + ":new");
} else {
window.$gz.eventBus.$emit(
"menu-disable-item",
FORM_KEY + ":duplicate"
);
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":new");
}
},
deep: true
}
},
computed: {
iconForType() {
return window.$gz.util.iconForType(this.obj.aType);
}
},
methods: {
navToTarget: function() {
window.$gz.eventBus.$emit("openobject", {
@@ -342,17 +342,19 @@ async function clickHandler(menuItem) {
break;
case "report":
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.ServiceBank,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
{
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.ServiceBank,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
break;
default:
@@ -411,7 +413,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"ServiceBank",
"ServiceBankDescription",

View File

@@ -2,9 +2,9 @@
<div>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<gz-extensions
ref="extensions"
:aya-type="$ay.ayt().ServiceBank"
:selected-items="selectedItems"
ref="extensions"
>
</gz-extensions>
<gz-data-table
@@ -15,9 +15,9 @@
:show-select="rights.read"
:reload="reload"
:rid-column-openable="false"
@selection-change="handleSelected"
data-cy="serviceBanksTable"
:pre-filter-mode="preFilterMode"
@selection-change="handleSelected"
@clear-pre-filter="clearPreFilter"
>
</gz-data-table>
@@ -27,6 +27,18 @@
<script>
const FORM_KEY = "service-bank-list";
export default {
data() {
return {
rights: window.$gz.role.defaultRightsObject(),
selectedItems: [],
reload: false,
clientCriteria: undefined,
preFilterMode: null,
objectId: null,
aType: null,
name: null
};
},
async created() {
const vm = this;
vm.rights = window.$gz.role.getRights(window.$gz.type.ServiceBank);
@@ -54,18 +66,6 @@ export default {
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
rights: window.$gz.role.defaultRightsObject(),
selectedItems: [],
reload: false,
clientCriteria: undefined,
preFilterMode: null,
objectId: null,
aType: null,
name: null
};
},
methods: {
handleSelected(selected) {
@@ -101,13 +101,15 @@ async function clickHandler(menuItem) {
});
break;
case "extensions":
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.ServiceBank
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
{
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.ServiceBank
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
}
}
break;
case "report":

View File

@@ -7,12 +7,12 @@
<v-row>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="name"
v-model="obj.name"
:readonly="formState.readOnly"
:label="$ay.t('Name')"
:rules="[form().required(this, 'name')]"
:error-messages="form().serverErrors(this, 'name')"
ref="name"
data-cy="name"
@input="fieldValueChanged('name')"
></v-text-field>
@@ -26,10 +26,10 @@
xl="3"
>
<v-text-field
ref="accountNumber"
v-model="obj.accountNumber"
:readonly="formState.readOnly"
:label="$ay.t('RateAccountNumber')"
ref="accountNumber"
data-cy="accountNumber"
:error-messages="form().serverErrors(this, 'accountNumber')"
@input="fieldValueChanged('accountNumber')"
@@ -38,10 +38,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-currency
ref="charge"
v-model="obj.charge"
:readonly="formState.readOnly"
:label="$ay.t('RateCharge')"
ref="charge"
data-cy="charge"
:rules="[
form().decimalValid(this, 'charge'),
@@ -54,10 +54,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-currency
ref="cost"
v-model="obj.cost"
:readonly="formState.readOnly"
:label="$ay.t('Cost')"
ref="cost"
data-cy="cost"
:rules="[
form().decimalValid(this, 'cost'),
@@ -76,14 +76,14 @@
xl="3"
>
<v-combobox
ref="unit"
v-model="obj.unit"
:readonly="formState.readOnly"
:label="$ay.t('RateUnitChargeDescriptionID')"
ref="unit"
data-cy="unit"
:error-messages="form().serverErrors(this, 'unit')"
@input="fieldValueChanged('unit')"
:items="selectLists.priorUnits"
@input="fieldValueChanged('unit')"
></v-combobox>
</v-col>
@@ -95,10 +95,10 @@
xl="3"
>
<v-checkbox
ref="contractOnly"
v-model="obj.contractOnly"
:readonly="formState.readOnly"
:label="$ay.t('RateContractRate')"
ref="contractOnly"
data-cy="contractOnly"
:error-messages="form().serverErrors(this, 'contractOnly')"
@change="fieldValueChanged('contractOnly')"
@@ -107,10 +107,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="active"
v-model="obj.active"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="active"
data-cy="active"
:error-messages="form().serverErrors(this, 'active')"
@change="fieldValueChanged('active')"
@@ -119,22 +119,22 @@
<!-- --------------------------------- -->
<v-col v-if="form().showMe(this, 'Notes')" cols="12">
<v-textarea
ref="notes"
v-model="obj.notes"
:readonly="formState.readOnly"
:label="$ay.t('ServiceRateNotes')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
<v-col v-if="form().showMe(this, 'Tags')" cols="12">
<gz-tag-picker
ref="tags"
v-model="obj.tags"
:readonly="formState.readOnly"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -143,11 +143,11 @@
<v-col cols="12">
<gz-custom-fields
ref="customFields"
v-model="obj.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly"
:parent-v-m="this"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -156,10 +156,10 @@
<v-col v-if="form().showMe(this, 'Wiki')" cols="12">
<gz-wiki
:aya-type="ayaType"
:aya-id="obj.id"
ref="wiki"
v-model="obj.wiki"
:aya-type="ayaType"
:aya-id="obj.id"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -186,65 +186,6 @@ const API_BASE_URL = "service-rate/";
const FORM_CUSTOM_TEMPLATE_KEY = "ServiceRate";
export default {
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.ServiceRate);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
@@ -310,6 +251,65 @@ export default {
deep: true
}
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.ServiceRate);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
canSave: function() {
return this.formState.valid && this.formState.dirty;
@@ -503,17 +503,19 @@ async function clickHandler(menuItem) {
break;
case "report":
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.ServiceRate,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
{
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.ServiceRate,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
break;
default:
@@ -618,7 +620,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"ServiceRate",
"Name",

View File

@@ -2,9 +2,9 @@
<div>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<gz-extensions
ref="extensions"
:aya-type="aType"
:selected-items="selectedItems"
ref="extensions"
>
</gz-extensions>
<gz-data-table
@@ -13,8 +13,8 @@
data-list-key="ServiceRateDataList"
:show-select="rights.read"
:reload="reload"
@selection-change="handleSelected"
data-cy="serviceRatesTable"
@selection-change="handleSelected"
>
</gz-data-table>
</div>
@@ -22,14 +22,6 @@
<script>
const FORM_KEY = "service-rate-list";
export default {
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.ServiceRate);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
rights: window.$gz.role.defaultRightsObject(),
@@ -38,6 +30,14 @@ export default {
reload: false
};
},
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.ServiceRate);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
handleSelected(selected) {
this.selectedItems = selected;
@@ -62,13 +62,15 @@ async function clickHandler(menuItem) {
});
break;
case "extensions":
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.ServiceRate
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
{
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.ServiceRate
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
}
}
break;
case "report":

View File

@@ -7,12 +7,12 @@
<v-row>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="name"
v-model="obj.name"
:readonly="formState.readOnly"
:label="$ay.t('Name')"
:rules="[form().required(this, 'name')]"
:error-messages="form().serverErrors(this, 'name')"
ref="name"
data-cy="name"
@input="fieldValueChanged('name')"
></v-text-field>
@@ -26,10 +26,10 @@
xl="3"
>
<gz-percent
ref="taxAPct"
v-model="obj.taxAPct"
:readonly="formState.readOnly"
:label="$ay.t('TaxCodeTaxA')"
ref="taxAPct"
data-cy="taxAPct"
:rules="[
form().decimalValid(this, 'taxAPct'),
@@ -48,10 +48,10 @@
xl="3"
>
<gz-percent
ref="taxBPct"
v-model="obj.taxBPct"
:readonly="formState.readOnly"
:label="$ay.t('TaxCodeTaxB')"
ref="taxBPct"
data-cy="taxBPct"
:rules="[
form().decimalValid(this, 'taxBPct'),
@@ -70,10 +70,10 @@
xl="3"
>
<v-checkbox
ref="taxOnTax"
v-model="obj.taxOnTax"
:readonly="formState.readOnly"
:label="$ay.t('TaxCodeTaxOnTax')"
ref="taxOnTax"
data-cy="taxOnTax"
:error-messages="form().serverErrors(this, 'taxOnTax')"
@change="fieldValueChanged('taxOnTax')"
@@ -81,10 +81,10 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="active"
v-model="obj.active"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="active"
data-cy="active"
:error-messages="form().serverErrors(this, 'active')"
@change="fieldValueChanged('active')"
@@ -93,22 +93,22 @@
<!-- --------------------------------- -->
<v-col v-if="form().showMe(this, 'Notes')" cols="12">
<v-textarea
ref="notes"
v-model="obj.notes"
:readonly="formState.readOnly"
:label="$ay.t('TaxCodeNotes')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
<v-col v-if="form().showMe(this, 'Tags')" cols="12">
<gz-tag-picker
ref="tags"
v-model="obj.tags"
:readonly="formState.readOnly"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -117,11 +117,11 @@
<v-col cols="12">
<gz-custom-fields
ref="customFields"
v-model="obj.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly"
:parent-v-m="this"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -130,10 +130,10 @@
<v-col v-if="form().showMe(this, 'Wiki')" cols="12">
<gz-wiki
:aya-type="ayaType"
:aya-id="obj.id"
ref="wiki"
v-model="obj.wiki"
:aya-type="ayaType"
:aya-id="obj.id"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -160,64 +160,6 @@ const API_BASE_URL = "tax-code/";
const FORM_CUSTOM_TEMPLATE_KEY = "TaxCode";
export default {
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.TaxCode);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
@@ -278,6 +220,64 @@ export default {
deep: true
}
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.TaxCode);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
canSave: function() {
return this.formState.valid && this.formState.dirty;
@@ -466,17 +466,19 @@ async function clickHandler(menuItem) {
m.vm.duplicate();
break;
case "report":
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.TaxCode,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
{
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.TaxCode,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
break;
default:
@@ -572,7 +574,7 @@ let JUST_DELETED = false;
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
await fetchTranslatedText();
await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY, vm);
}
@@ -580,7 +582,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"TaxCode",
"Name",

View File

@@ -2,9 +2,9 @@
<div>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<gz-extensions
ref="extensions"
:aya-type="aType"
:selected-items="selectedItems"
ref="extensions"
>
</gz-extensions>
<gz-data-table
@@ -13,8 +13,8 @@
data-list-key="TaxCodeDataList"
:show-select="rights.read"
:reload="reload"
@selection-change="handleSelected"
data-cy="taxCodesTable"
@selection-change="handleSelected"
>
</gz-data-table>
</div>
@@ -22,14 +22,6 @@
<script>
const FORM_KEY = "tax-code-list";
export default {
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.TaxCode);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
rights: window.$gz.role.defaultRightsObject(),
@@ -38,6 +30,14 @@ export default {
reload: false
};
},
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.TaxCode);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
handleSelected(selected) {
this.selectedItems = selected;
@@ -62,11 +62,13 @@ async function clickHandler(menuItem) {
});
break;
case "extensions":
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(window.$gz.type.TaxCode)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
{
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(window.$gz.type.TaxCode)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
}
}
break;
case "report":

View File

@@ -7,12 +7,12 @@
<v-row>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="name"
v-model="obj.name"
:readonly="formState.readOnly"
:label="$ay.t('Name')"
:rules="[form().required(this, 'name')]"
:error-messages="form().serverErrors(this, 'name')"
ref="name"
data-cy="name"
@input="fieldValueChanged('name')"
></v-text-field>
@@ -26,10 +26,10 @@
xl="3"
>
<v-text-field
ref="accountNumber"
v-model="obj.accountNumber"
:readonly="formState.readOnly"
:label="$ay.t('RateAccountNumber')"
ref="accountNumber"
data-cy="accountNumber"
:error-messages="form().serverErrors(this, 'accountNumber')"
@input="fieldValueChanged('accountNumber')"
@@ -38,10 +38,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-currency
ref="charge"
v-model="obj.charge"
:readonly="formState.readOnly"
:label="$ay.t('RateCharge')"
ref="charge"
data-cy="charge"
:rules="[
form().decimalValid(this, 'charge'),
@@ -54,10 +54,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-currency
ref="cost"
v-model="obj.cost"
:readonly="formState.readOnly"
:label="$ay.t('Cost')"
ref="cost"
data-cy="cost"
:rules="[
form().decimalValid(this, 'cost'),
@@ -76,14 +76,14 @@
xl="3"
>
<v-combobox
ref="unit"
v-model="obj.unit"
:readonly="formState.readOnly"
:label="$ay.t('RateUnitChargeDescriptionID')"
ref="unit"
data-cy="unit"
:error-messages="form().serverErrors(this, 'unit')"
@input="fieldValueChanged('unit')"
:items="selectLists.priorUnits"
@input="fieldValueChanged('unit')"
></v-combobox>
</v-col>
<v-col
@@ -94,10 +94,10 @@
xl="3"
>
<v-checkbox
ref="contractOnly"
v-model="obj.contractOnly"
:readonly="formState.readOnly"
:label="$ay.t('RateContractRate')"
ref="contractOnly"
data-cy="contractOnly"
:error-messages="form().serverErrors(this, 'contractOnly')"
@change="fieldValueChanged('contractOnly')"
@@ -105,10 +105,10 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="active"
v-model="obj.active"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="active"
data-cy="active"
:error-messages="form().serverErrors(this, 'active')"
@change="fieldValueChanged('active')"
@@ -117,22 +117,22 @@
<!-- --------------------------------- -->
<v-col v-if="form().showMe(this, 'Notes')" cols="12">
<v-textarea
ref="notes"
v-model="obj.notes"
:readonly="formState.readOnly"
:label="$ay.t('TravelRateNotes')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
@input="fieldValueChanged('notes')"
></v-textarea>
</v-col>
<v-col v-if="form().showMe(this, 'Tags')" cols="12">
<gz-tag-picker
ref="tags"
v-model="obj.tags"
:readonly="formState.readOnly"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
@@ -141,11 +141,11 @@
<v-col cols="12">
<gz-custom-fields
ref="customFields"
v-model="obj.customFields"
:form-key="formCustomTemplateKey"
:readonly="formState.readOnly"
:parent-v-m="this"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
@@ -154,10 +154,10 @@
<v-col v-if="form().showMe(this, 'Wiki')" cols="12">
<gz-wiki
:aya-type="ayaType"
:aya-id="obj.id"
ref="wiki"
v-model="obj.wiki"
:aya-type="ayaType"
:aya-id="obj.id"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
@@ -184,62 +184,6 @@ const API_BASE_URL = "travel-rate/";
const FORM_CUSTOM_TEMPLATE_KEY = "TravelRate";
export default {
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.TravelRate);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY,
@@ -303,6 +247,62 @@ export default {
deep: true
}
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.TravelRate);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
let setDirty = false;
//id 0 means create or duplicate to new
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
} else {
await vm.getDataFromApi(vm.$route.params.recordid);
}
} else {
//Might be a duplicate and contain another record
if (this.$route.params.obj) {
this.obj = this.$route.params.obj;
this.obj.concurrency = undefined;
this.obj.id = 0;
this.obj.name = `${this.obj.name} - ${window.$gz.translation.get(
"Copy"
)}`;
setDirty = true;
}
}
window.$gz.form.setFormState({
vm: vm,
loading: false,
dirty: setDirty,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty || JUST_DELETED) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
canSave: function() {
return this.formState.valid && this.formState.dirty;
@@ -489,17 +489,19 @@ async function clickHandler(menuItem) {
m.vm.duplicate();
break;
case "report":
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.TravelRate,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
{
const res = await m.vm.$refs.reportSelector.open(
{
AType: window.$gz.type.TravelRate,
selectedRowIds: [m.vm.obj.id]
},
m.id
);
if (res == null) {
return;
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
}
window.$gz.form.setLastReportMenuItem(FORM_KEY, res, m.vm);
break;
default:
window.$gz.eventBus.$emit(
@@ -605,7 +607,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"TravelRate",
"Name",

View File

@@ -2,9 +2,9 @@
<div>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<gz-extensions
ref="extensions"
:aya-type="aType"
:selected-items="selectedItems"
ref="extensions"
>
</gz-extensions>
<gz-data-table
@@ -13,8 +13,8 @@
data-list-key="TravelRateDataList"
:show-select="rights.read"
:reload="reload"
@selection-change="handleSelected"
data-cy="travelRatesTable"
@selection-change="handleSelected"
>
</gz-data-table>
</div>
@@ -22,14 +22,6 @@
<script>
const FORM_KEY = "travel-rate-list";
export default {
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.TravelRate);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
rights: window.$gz.role.defaultRightsObject(),
@@ -38,6 +30,14 @@ export default {
reload: false
};
},
created() {
this.rights = window.$gz.role.getRights(window.$gz.type.TravelRate);
window.$gz.eventBus.$on("menu-click", clickHandler);
generateMenu(this);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
handleSelected(selected) {
this.selectedItems = selected;
@@ -62,13 +62,15 @@ async function clickHandler(menuItem) {
});
break;
case "extensions":
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.TravelRate
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
{
const res = await m.vm.$refs.extensions.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.TravelRate
)
);
if (res && res.refresh == true) {
m.vm.reload = !m.vm.reload;
}
}
break;
case "report":

View File

@@ -1,7 +1,7 @@
<template>
<div>
<v-row>
<gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
<gz-error :error-box-message="formState.errorBoxMessage" />
<v-col cols="12">
<gz-data-table
v-if="!jobActive"
@@ -10,17 +10,12 @@
:show-select="true"
:single-select="false"
:reload="reload"
@selection-change="handleSelected"
data-cy="attachTable"
>
</gz-data-table>
@selection-change="handleSelected"
/>
<template v-if="jobActive">
<v-progress-circular
indeterminate
color="primary"
:size="60"
></v-progress-circular>
<v-progress-circular indeterminate color="primary" :size="60" />
</template>
</v-col>
</v-row>
@@ -37,25 +32,25 @@
item-text="name"
item-value="id"
:label="$ay.t('AyaType')"
></v-select>
/>
<gz-pick-list
v-if="moveType != 0"
v-model="moveId"
:aya-type="moveType"
:show-edit-icon="false"
:include-inactive="true"
v-model="moveId"
label="Id"
></gz-pick-list>
/>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="moveDialog = false">{{
$ay.t("Cancel")
}}</v-btn>
<v-btn color="blue darken-1" text @click="moveSelected()">{{
$ay.t("OK")
}}</v-btn>
<v-spacer />
<v-btn color="blue darken-1" text @click="moveDialog = false">
{{ $ay.t("Cancel") }}
</v-btn>
<v-btn color="blue darken-1" text @click="moveSelected()">
{{ $ay.t("OK") }}
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
@@ -65,17 +60,6 @@
<script>
const FORM_KEY = "adm-attachments";
export default {
async created() {
this.rights = window.$gz.role.getRights(window.$gz.type.FileAttachment);
window.$gz.eventBus.$on("menu-click", clickHandler);
await fetchTranslatedText(this);
await populateSelectionLists(this);
generateMenu(this);
this.handleSelected([]); //start out read only no selection state for batch ops options
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
jobActive: false,
@@ -100,6 +84,17 @@ export default {
}
};
},
async created() {
this.rights = window.$gz.role.getRights(window.$gz.type.FileAttachment);
window.$gz.eventBus.$on("menu-click", clickHandler);
await fetchTranslatedText(this);
await populateSelectionLists(this);
generateMenu(this);
this.handleSelected([]); //start out read only no selection state for batch ops options
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
canBatchOp() {
return (
@@ -294,7 +289,7 @@ function generateMenu(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"StartAttachmentMaintenanceJob",
"JobExclusiveWarning",

View File

@@ -83,30 +83,6 @@
//
const FORM_KEY = "adm-global-logo";
export default {
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
vm.smallUrl = `${window.$gz.api.logoUrl("small")}?x=${Date.now()}`;
vm.mediumUrl = `${window.$gz.api.logoUrl("medium")}?x=${Date.now()}`;
vm.largeUrl = `${window.$gz.api.logoUrl("large")}?x=${Date.now()}`;
vm.fileSizeExceededWarning = vm.$ay
.t("AyaFileFileTooLarge")
.replace("{0}", "512KiB");
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
data() {
return {
uploadSmall: null,
@@ -132,6 +108,30 @@ export default {
]
};
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
vm.smallUrl = `${window.$gz.api.logoUrl("small")}?x=${Date.now()}`;
vm.mediumUrl = `${window.$gz.api.logoUrl("medium")}?x=${Date.now()}`;
vm.largeUrl = `${window.$gz.api.logoUrl("large")}?x=${Date.now()}`;
vm.fileSizeExceededWarning = vm.$ay
.t("AyaFileFileTooLarge")
.replace("{0}", "512KiB");
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
methods: {
imageUrl(size) {
return window.$gz.api.logoUrl(size);
@@ -267,7 +267,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"SmallLogo",
"MediumLogo",

View File

@@ -13,10 +13,10 @@
<gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="purchaseOrderNextSerial"
v-model="obj.purchaseOrderNextSerial"
:readonly="formState.readOnly"
:label="$ay.t('NextPONumber')"
ref="purchaseOrderNextSerial"
data-cy="purchaseOrderNextSerial"
:rules="[
form().integerValid(this, 'purchaseOrderNextSerial'),
@@ -25,8 +25,8 @@
:error-messages="
form().serverErrors(this, 'purchaseOrderNextSerial')
"
@input="fieldValueChanged('purchaseOrderNextSerial')"
append-outer-icon="$ayiSave"
@input="fieldValueChanged('purchaseOrderNextSerial')"
@click:append-outer="
submit(ayaTypes().PurchaseOrder, obj.purchaseOrderNextSerial)
"
@@ -35,18 +35,18 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="workorderNextSerial"
v-model="obj.workorderNextSerial"
:readonly="formState.readOnly"
:label="$ay.t('NextWorkorderNumber')"
ref="workorderNextSerial"
data-cy="workorderNextSerial"
:rules="[
form().integerValid(this, 'workorderNextSerial'),
form().required(this, 'workorderNextSerial')
]"
:error-messages="form().serverErrors(this, 'workorderNextSerial')"
@input="fieldValueChanged('workorderNextSerial')"
append-outer-icon="$ayiSave"
@input="fieldValueChanged('workorderNextSerial')"
@click:append-outer="
submit(ayaTypes().WorkOrder, obj.workorderNextSerial)
"
@@ -55,18 +55,18 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="quoteNextSerial"
v-model="obj.quoteNextSerial"
:readonly="formState.readOnly"
:label="$ay.t('NextQuoteNumber')"
ref="quoteNextSerial"
data-cy="quoteNextSerial"
:rules="[
form().integerValid(this, 'quoteNextSerial'),
form().required(this, 'quoteNextSerial')
]"
:error-messages="form().serverErrors(this, 'quoteNextSerial')"
@input="fieldValueChanged('quoteNextSerial')"
append-outer-icon="$ayiSave"
@input="fieldValueChanged('quoteNextSerial')"
@click:append-outer="
submit(ayaTypes().Quote, obj.quoteNextSerial)
"
@@ -75,18 +75,18 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="pmNextSerial"
v-model="obj.pmNextSerial"
:readonly="formState.readOnly"
:label="$ay.t('NextPMNumber')"
ref="pmNextSerial"
data-cy="pmNextSerial"
:rules="[
form().integerValid(this, 'pmNextSerial'),
form().required(this, 'pmNextSerial')
]"
:error-messages="form().serverErrors(this, 'pmNextSerial')"
@input="fieldValueChanged('pmNextSerial')"
append-outer-icon="$ayiSave"
@input="fieldValueChanged('pmNextSerial')"
@click:append-outer="submit(ayaTypes().PM, obj.pmNextSerial)"
></v-text-field>
</v-col>
@@ -102,25 +102,6 @@
const FORM_KEY = "adm-global-seeds";
const API_BASE_URL = "global-biz-setting/seeds/";
export default {
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
await vm.getDataFromApi();
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
data() {
return {
obj: {
@@ -158,6 +139,25 @@ export default {
deep: true
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
await vm.getDataFromApi();
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
methods: {
ayaTypes: function() {
return window.$gz.type;
@@ -282,7 +282,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"GlobalNextSeeds",
"NextPONumber",

View File

@@ -18,9 +18,9 @@
item-text="name"
item-value="id"
:label="$ay.t('PickListTemplates')"
@input="templateSelected"
data-cy="selectTemplate"
:disabled="formState.dirty"
@input="templateSelected"
>
</v-select>
</v-col>
@@ -35,13 +35,13 @@
</v-card-subtitle>
<v-card-text>
<v-checkbox
:ref="item.key"
v-model="item.include"
:readonly="formState.readOnly"
:label="$ay.t('Include')"
:ref="item.key"
:disabled="item.required"
@change="includeChanged(item)"
:data-cy="item.key + 'Include'"
@change="includeChanged(item)"
></v-checkbox>
<!-- RE-ORDER CONTROL -->
<div class="d-flex justify-space-between">
@@ -85,27 +85,6 @@ export default {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
//init disable save button so it can be enabled only on edit to show dirty form
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":delete");
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
data() {
return {
obj: {
@@ -157,8 +136,29 @@ export default {
}
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
async created() {
const vm = this;
try {
await initForm(vm);
vm.formState.ready = true;
vm.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: this would normally be in getDataFromAPI but this form doesn't really need that function so doing it here
generateMenu(vm);
//init disable save button so it can be enabled only on edit to show dirty form
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":save");
window.$gz.eventBus.$emit("menu-disable-item", FORM_KEY + ":delete");
vm.formState.loading = false;
} catch (err) {
vm.formState.ready = true;
window.$gz.errorHandler.handleFormError(err, vm);
}
},
methods: {
includeChanged: function(item) {
includeChanged: function() {
window.$gz.form.setFormState({
vm: this,
dirty: true
@@ -404,7 +404,7 @@ function generateMenu(vm) {
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
await fetchTranslatedText();
await populateSelectionLists(vm);
}
@@ -412,7 +412,7 @@ async function initForm(vm) {
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations(["Include", "ResetToDefault"]);
}

View File

@@ -12,12 +12,12 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="taxPartPurchaseId"
v-model="obj.taxPartPurchaseId"
:aya-type="ayaTypes().TaxCode"
show-edit-icon
v-model="obj.taxPartPurchaseId"
:readonly="formState.readOnly"
:label="$ay.t('GlobalTaxPartPurchaseID')"
ref="taxPartPurchaseId"
data-cy="taxPartPurchaseId"
:error-messages="form().serverErrors(this, `taxPartPurchaseId`)"
@input="fieldValueChanged(`taxPartPurchaseId`)"
@@ -26,12 +26,12 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="taxRateSaleId"
v-model="obj.taxRateSaleId"
:aya-type="ayaTypes().TaxCode"
show-edit-icon
v-model="obj.taxRateSaleId"
:readonly="formState.readOnly"
:label="$ay.t('GlobalTaxRateSaleID')"
ref="taxRateSaleId"
data-cy="taxRateSaleId"
:error-messages="form().serverErrors(this, `taxRateSaleId`)"
@input="fieldValueChanged(`taxRateSaleId`)"
@@ -40,12 +40,12 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
ref="taxPartSaleId"
v-model="obj.taxPartSaleId"
:aya-type="ayaTypes().TaxCode"
show-edit-icon
v-model="obj.taxPartSaleId"
:readonly="formState.readOnly"
:label="$ay.t('GlobalTaxPartSaleID')"
ref="taxPartSaleId"
data-cy="taxPartSaleId"
:error-messages="form().serverErrors(this, `taxPartSaleId`)"
@input="fieldValueChanged(`taxPartSaleId`)"
@@ -54,10 +54,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="filterCaseSensitive"
v-model="obj.filterCaseSensitive"
:readonly="formState.readOnly"
:label="$ay.t('GlobalFilterCaseSensitive')"
ref="filterCaseSensitive"
data-cy="filterCaseSensitive"
@change="fieldValueChanged('filterCaseSensitive')"
></v-checkbox>
@@ -65,10 +65,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="useInventory"
v-model="obj.useInventory"
:readonly="formState.readOnly"
:label="$ay.t('GlobalUseInventory')"
ref="useInventory"
data-cy="useInventory"
@change="fieldValueChanged('useInventory')"
></v-checkbox>
@@ -76,11 +76,11 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-duration-picker
ref="workOrderCompleteByAge"
v-model="obj.workOrderCompleteByAge"
:readonly="formState.readOnly"
:label="$ay.t('GlobalWorkOrderCompleteByAge')"
:show-seconds="false"
ref="workOrderCompleteByAge"
data-cy="workOrderCompleteByAge"
:error-messages="
form().serverErrors(this, 'workOrderCompleteByAge')
@@ -91,10 +91,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
ref="allowScheduleConflicts"
v-model="obj.allowScheduleConflicts"
:readonly="formState.readOnly"
:label="$ay.t('GlobalAllowScheduleConflicts')"
ref="allowScheduleConflicts"
data-cy="allowScheduleConflicts"
@change="fieldValueChanged('allowScheduleConflicts')"
></v-checkbox>
@@ -102,10 +102,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="workLaborScheduleDefaultMinutes"
v-model="obj.workLaborScheduleDefaultMinutes"
:readonly="formState.readOnly"
:label="$ay.t('GlobalLaborSchedUserDfltTimeSpan')"
ref="workLaborScheduleDefaultMinutes"
data-cy="workLaborScheduleDefaultMinutes"
:rules="[
form().integerValid(this, 'workLaborScheduleDefaultMinutes'),
@@ -120,10 +120,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="workOrderTravelDefaultMinutes"
v-model="obj.workOrderTravelDefaultMinutes"
:readonly="formState.readOnly"
:label="$ay.t('GlobalTravelDfltTimeSpan')"
ref="workOrderTravelDefaultMinutes"
data-cy="workOrderTravelDefaultMinutes"
:rules="[
form().integerValid(this, 'workOrderTravelDefaultMinutes'),
@@ -150,10 +150,10 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-url
ref="webAddress"
v-model="obj.webAddress"
:readonly="formState.readOnly"
:label="$ay.t('WebAddress')"
ref="webAddress"
data-cy="webAddress"
:error-messages="form().serverErrors(this, 'webAddress')"
@input="fieldValueChanged('webAddress')"
@@ -162,10 +162,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-email
ref="emailAddress"
v-model="obj.emailAddress"
:readonly="formState.readOnly"
:label="$ay.t('CompanyEmail')"
ref="emailAddress"
data-cy="emailAddress"
:error-messages="form().serverErrors(this, 'emailAddress')"
@input="fieldValueChanged('emailAddress')"
@@ -174,10 +174,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-phone
ref="phone1"
v-model="obj.phone1"
:readonly="formState.readOnly"
:label="$ay.t('CompanyPhone1')"
ref="phone1"
data-cy="phone1"
:error-messages="form().serverErrors(this, 'phone1')"
@input="fieldValueChanged('phone1')"
@@ -186,10 +186,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-phone
ref="phone2"
v-model="obj.phone2"
:readonly="formState.readOnly"
:label="$ay.t('CompanyPhone2')"
ref="phone2"
data-cy="phone2"
:error-messages="form().serverErrors(this, 'phone2')"
@input="fieldValueChanged('phone2')"
@@ -203,10 +203,10 @@
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="address"
v-model="obj.address"
:readonly="formState.readOnly"
:label="$ay.t('AddressDeliveryAddress')"
ref="address"
data-cy="address"
:error-messages="form().serverErrors(this, 'address')"
@input="fieldValueChanged('address')"
@@ -215,10 +215,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="city"
v-model="obj.city"
:readonly="formState.readOnly"
:label="$ay.t('AddressCity')"
ref="city"
data-cy="city"
:error-messages="form().serverErrors(this, 'city')"
@input="fieldValueChanged('city')"
@@ -227,10 +227,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="region"
v-model="obj.region"
:readonly="formState.readOnly"
:label="$ay.t('AddressStateProv')"
ref="region"
data-cy="region"
:error-messages="form().serverErrors(this, 'region')"
@input="fieldValueChanged('region')"
@@ -239,10 +239,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="country"
v-model="obj.country"
:readonly="formState.readOnly"
:label="$ay.t('AddressCountry')"
ref="country"
data-cy="country"
:error-messages="form().serverErrors(this, 'country')"
@input="fieldValueChanged('country')"
@@ -251,29 +251,29 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-decimal
ref="latitude"
v-model="obj.latitude"
:readonly="formState.readOnly"
:label="$ay.t('AddressLatitude')"
ref="latitude"
data-cy="latitude"
:rules="[form().decimalValid(this, 'latitude')]"
:error-messages="form().serverErrors(this, 'latitude')"
@input="fieldValueChanged('latitude')"
:precision="6"
@input="fieldValueChanged('latitude')"
></gz-decimal>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-decimal
ref="longitude"
v-model="obj.longitude"
:readonly="formState.readOnly"
:label="$ay.t('AddressLongitude')"
ref="longitude"
data-cy="longitude"
:rules="[form().decimalValid(this, 'longitude')]"
:error-messages="form().serverErrors(this, 'longitude')"
@input="fieldValueChanged('longitude')"
:precision="6"
@input="fieldValueChanged('longitude')"
></gz-decimal>
</v-col>
@@ -285,10 +285,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="postAddress"
v-model="obj.postAddress"
:readonly="formState.readOnly"
:label="$ay.t('AddressPostalDeliveryAddress')"
ref="postAddress"
data-cy="postAddress"
:error-messages="form().serverErrors(this, 'postAddress')"
@input="fieldValueChanged('postAddress')"
@@ -297,10 +297,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="postCity"
v-model="obj.postCity"
:readonly="formState.readOnly"
:label="$ay.t('AddressPostalCity')"
ref="postCity"
data-cy="postCity"
:error-messages="form().serverErrors(this, 'postCity')"
@input="fieldValueChanged('postCity')"
@@ -309,10 +309,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="postRegion"
v-model="obj.postRegion"
:readonly="formState.readOnly"
:label="$ay.t('AddressPostalStateProv')"
ref="postRegion"
data-cy="postRegion"
:error-messages="form().serverErrors(this, 'postRegion')"
@input="fieldValueChanged('postRegion')"
@@ -321,10 +321,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="postCountry"
v-model="obj.postCountry"
:readonly="formState.readOnly"
:label="$ay.t('AddressPostalCountry')"
ref="postCountry"
data-cy="postCountry"
:error-messages="form().serverErrors(this, 'postCountry')"
@input="fieldValueChanged('postCountry')"
@@ -333,10 +333,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="postCode"
v-model="obj.postCode"
:readonly="formState.readOnly"
:label="$ay.t('AddressPostalPostal')"
ref="postCode"
data-cy="postCode"
:error-messages="form().serverErrors(this, 'postCode')"
@input="fieldValueChanged('postCode')"
@@ -367,10 +367,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="signatureTitle"
v-model="obj.signatureTitle"
:readonly="formState.readOnly"
:label="$ay.t('GlobalSignatureTitle')"
ref="signatureTitle"
data-cy="signatureTitle"
:error-messages="form().serverErrors(this, 'signatureTitle')"
@input="fieldValueChanged('signatureTitle')"
@@ -379,10 +379,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="signatureHeader"
v-model="obj.signatureHeader"
:readonly="formState.readOnly"
:label="$ay.t('GlobalSignatureHeader')"
ref="signatureHeader"
data-cy="signatureHeader"
:error-messages="form().serverErrors(this, 'signatureHeader')"
@input="fieldValueChanged('signatureHeader')"
@@ -391,10 +391,10 @@
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
ref="signatureFooter"
v-model="obj.signatureFooter"
:readonly="formState.readOnly"
:label="$ay.t('GlobalSignatureFooter')"
ref="signatureFooter"
data-cy="signatureFooter"
:error-messages="form().serverErrors(this, 'signatureFooter')"
@input="fieldValueChanged('signatureFooter')"
@@ -420,10 +420,10 @@
<v-row>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowCSR"
v-model="obj.customerAllowCSR"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="customerAllowCSR"
data-cy="customerAllowCSR"
:error-messages="
form().serverErrors(this, 'customerAllowCSR')
@@ -434,10 +434,10 @@
<template v-if="obj.customerAllowCSR">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowCSRInTags"
v-model="obj.customerAllowCSRInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowCSRInTags"
data-cy="customerAllowCSRInTags"
:error-messages="
form().serverErrors(this, 'customerAllowCSRInTags')
@@ -448,6 +448,7 @@
<v-col cols="12">
<v-textarea
ref="customerServiceRequestInfoText"
v-model="obj.customerServiceRequestInfoText"
:readonly="formState.readOnly"
:label="$ay.t('CSRInfoText')"
@@ -457,21 +458,20 @@
'customerServiceRequestInfoText'
)
"
ref="customerServiceRequestInfoText"
data-cy="customerServiceRequestInfoText"
auto-grow
@input="
fieldValueChanged('customerServiceRequestInfoText')
"
auto-grow
></v-textarea>
</v-col>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowCreateUnit"
v-model="obj.customerAllowCreateUnit"
:readonly="formState.readOnly"
:label="$ay.t('CustomerAllowCreateUnit')"
ref="customerAllowCreateUnit"
data-cy="customerAllowCreateUnit"
:error-messages="
form().serverErrors(this, 'customerAllowCreateUnit')
@@ -482,12 +482,12 @@
<template v-if="obj.customerAllowCreateUnit">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowCreateUnitInTags"
v-model="obj.customerAllowCreateUnitInTags"
:readonly="formState.readOnly"
:label="
$ay.t('ContactCustomerHeadOfficeTaggedWith')
"
ref="customerAllowCreateUnitInTags"
data-cy="customerAllowCreateUnitInTags"
:error-messages="
form().serverErrors(
@@ -515,10 +515,10 @@
<v-row>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowViewWO"
v-model="obj.customerAllowViewWO"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="customerAllowViewWO"
data-cy="customerAllowViewWO"
:error-messages="
form().serverErrors(this, 'customerAllowViewWO')
@@ -529,10 +529,10 @@
<template v-if="obj.customerAllowViewWO">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowViewWOInTags"
v-model="obj.customerAllowViewWOInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowViewWOInTags"
data-cy="customerAllowViewWOInTags"
:error-messages="
form().serverErrors(
@@ -556,13 +556,13 @@
<v-row>
<v-col cols="12">
<gz-pick-list
ref="customerDefaultWorkOrderReportId"
v-model="obj.customerDefaultWorkOrderReportId"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerDefaultWorkOrderReportId"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerDefaultWorkOrderReportId"
data-cy="customerDefaultWorkOrderReportId"
:error-messages="
form().serverErrors(
@@ -581,10 +581,10 @@
<!-- ------------ -->
<v-col cols="12" sm="6">
<gz-tag-picker
ref="customerWorkOrderReport1Tags"
v-model="obj.customerWorkOrderReport1Tags"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderCustomerTaggedWith')"
ref="customerWorkOrderReport1Tags"
data-cy="customerWorkOrderReport1Tags"
:error-messages="
form().serverErrors(
@@ -602,13 +602,13 @@
<v-col cols="12" sm="6">
<gz-pick-list
ref="customerTagWorkOrderReport1Id"
v-model="obj.customerTagWorkOrderReport1Id"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerTagWorkOrderReport1Id"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerTagWorkOrderReport1Id"
data-cy="customerTagWorkOrderReport1Id"
:error-messages="
form().serverErrors(
@@ -627,10 +627,10 @@
<!-- ------------ -->
<v-col cols="12" sm="6">
<gz-tag-picker
ref="customerWorkOrderReport2Tags"
v-model="obj.customerWorkOrderReport2Tags"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderCustomerTaggedWith')"
ref="customerWorkOrderReport2Tags"
data-cy="customerWorkOrderReport2Tags"
:error-messages="
form().serverErrors(
@@ -648,13 +648,13 @@
<v-col cols="12" sm="6">
<gz-pick-list
ref="customerTagWorkOrderReport2Id"
v-model="obj.customerTagWorkOrderReport2Id"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerTagWorkOrderReport2Id"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerTagWorkOrderReport2Id"
data-cy="customerTagWorkOrderReport2Id"
:error-messages="
form().serverErrors(
@@ -673,10 +673,10 @@
<!-- ------------ -->
<v-col cols="12" sm="6">
<gz-tag-picker
ref="customerWorkOrderReport3Tags"
v-model="obj.customerWorkOrderReport3Tags"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderCustomerTaggedWith')"
ref="customerWorkOrderReport3Tags"
data-cy="customerWorkOrderReport3Tags"
:error-messages="
form().serverErrors(
@@ -694,13 +694,13 @@
<v-col cols="12" sm="6">
<gz-pick-list
ref="customerTagWorkOrderReport3Id"
v-model="obj.customerTagWorkOrderReport3Id"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerTagWorkOrderReport3Id"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerTagWorkOrderReport3Id"
data-cy="customerTagWorkOrderReport3Id"
:error-messages="
form().serverErrors(
@@ -719,10 +719,10 @@
<!-- ------------ -->
<v-col cols="12" sm="6">
<gz-tag-picker
ref="customerWorkOrderReport4Tags"
v-model="obj.customerWorkOrderReport4Tags"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderCustomerTaggedWith')"
ref="customerWorkOrderReport4Tags"
data-cy="customerWorkOrderReport4Tags"
:error-messages="
form().serverErrors(
@@ -740,13 +740,13 @@
<v-col cols="12" sm="6">
<gz-pick-list
ref="customerTagWorkOrderReport4Id"
v-model="obj.customerTagWorkOrderReport4Id"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerTagWorkOrderReport4Id"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerTagWorkOrderReport4Id"
data-cy="customerTagWorkOrderReport4Id"
:error-messages="
form().serverErrors(
@@ -765,10 +765,10 @@
<!-- ------------ -->
<v-col cols="12" sm="6">
<gz-tag-picker
ref="customerWorkOrderReport5Tags"
v-model="obj.customerWorkOrderReport5Tags"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderCustomerTaggedWith')"
ref="customerWorkOrderReport5Tags"
data-cy="customerWorkOrderReport5Tags"
:error-messages="
form().serverErrors(
@@ -786,13 +786,13 @@
<v-col cols="12" sm="6">
<gz-pick-list
ref="customerTagWorkOrderReport5Id"
v-model="obj.customerTagWorkOrderReport5Id"
:aya-type="ayaTypes().Report"
:variant="ayaTypes().WorkOrder.toString()"
show-edit-icon
v-model="obj.customerTagWorkOrderReport5Id"
:readonly="formState.readOnly"
:label="$ay.t('DefaultReport')"
ref="customerTagWorkOrderReport5Id"
data-cy="customerTagWorkOrderReport5Id"
:error-messages="
form().serverErrors(
@@ -820,10 +820,10 @@
<v-row>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowWOWiki"
v-model="obj.customerAllowWOWiki"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="customerAllowWOWiki"
data-cy="customerAllowWOWiki"
:error-messages="
form().serverErrors(
@@ -839,6 +839,7 @@
<template v-if="obj.customerAllowWOWiki">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowWOWikiInTags"
v-model="obj.customerAllowWOWikiInTags"
:readonly="formState.readOnly"
:label="
@@ -846,7 +847,6 @@
'WorkOrderContactCustomerHeadOfficeTaggedWith'
)
"
ref="customerAllowWOWikiInTags"
data-cy="customerAllowWOWikiInTags"
:error-messages="
form().serverErrors(
@@ -875,10 +875,10 @@
<v-row>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowWOAttachments"
v-model="obj.customerAllowWOAttachments"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="customerAllowWOAttachments"
data-cy="customerAllowWOAttachments"
:error-messages="
form().serverErrors(
@@ -896,6 +896,7 @@
<template v-if="obj.customerAllowWOAttachments">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowWOAttachmentsInTags"
v-model="
obj.customerAllowWOAttachmentsInTags
"
@@ -905,7 +906,6 @@
'WorkOrderContactCustomerHeadOfficeTaggedWith'
)
"
ref="customerAllowWOAttachmentsInTags"
data-cy="customerAllowWOAttachmentsInTags"
:error-messages="
form().serverErrors(
@@ -939,10 +939,10 @@
<v-row>
<v-col cols="12" sm="6" lg="2">
<v-checkbox
ref="customerAllowUserSettings"
v-model="obj.customerAllowUserSettings"
:readonly="formState.readOnly"
:label="$ay.t('Active')"
ref="customerAllowUserSettings"
data-cy="customerAllowUserSettings"
:error-messages="
form().serverErrors(this, 'customerAllowUserSettings')
@@ -953,10 +953,10 @@
<template v-if="obj.customerAllowUserSettings">
<v-col cols="12" sm="6" lg="10">
<gz-tag-picker
ref="customerAllowUserSettingsInTags"
v-model="obj.customerAllowUserSettingsInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowUserSettingsInTags"
data-cy="customerAllowUserSettingsInTags"
:error-messages="
form().serverErrors(
@@ -983,10 +983,10 @@
<v-row>
<v-col cols="12" sm="6" lg="3">
<v-checkbox
ref="customerAllowNotifyServiceImminent"
v-model="obj.customerAllowNotifyServiceImminent"
:readonly="formState.readOnly"
:label="$ay.t('NotifyEventCustomerServiceImminent')"
ref="customerAllowNotifyServiceImminent"
data-cy="customerAllowNotifyServiceImminent"
:error-messages="
form().serverErrors(
@@ -1003,16 +1003,16 @@
</v-col>
<v-col
v-if="obj.customerAllowNotifyServiceImminent"
cols="12"
sm="6"
lg="9"
v-if="obj.customerAllowNotifyServiceImminent"
>
<gz-tag-picker
ref="customerAllowNotifyServiceImminentInTags"
v-model="obj.customerAllowNotifyServiceImminentInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowNotifyServiceImminentInTags"
data-cy="customerAllowNotifyServiceImminentInTags"
:error-messages="
form().serverErrors(
@@ -1032,10 +1032,10 @@
<v-col cols="12" sm="6" lg="3">
<v-checkbox
ref="customerAllowNotifyCSRAccepted"
v-model="obj.customerAllowNotifyCSRAccepted"
:readonly="formState.readOnly"
:label="$ay.t('NotifyEventCSRAccepted')"
ref="customerAllowNotifyCSRAccepted"
data-cy="customerAllowNotifyCSRAccepted"
:error-messages="
form().serverErrors(
@@ -1049,16 +1049,16 @@
></v-checkbox>
</v-col>
<v-col
v-if="obj.customerAllowNotifyCSRAccepted"
cols="12"
sm="6"
lg="9"
v-if="obj.customerAllowNotifyCSRAccepted"
>
<gz-tag-picker
ref="customerAllowNotifyCSRAcceptedInTags"
v-model="obj.customerAllowNotifyCSRAcceptedInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowNotifyCSRAcceptedInTags"
data-cy="customerAllowNotifyCSRAcceptedInTags"
:error-messages="
form().serverErrors(
@@ -1078,10 +1078,10 @@
<v-col cols="12" sm="6" lg="3">
<v-checkbox
ref="customerAllowNotifyCSRRejected"
v-model="obj.customerAllowNotifyCSRRejected"
:readonly="formState.readOnly"
:label="$ay.t('NotifyEventCSRRejected')"
ref="customerAllowNotifyCSRRejected"
data-cy="customerAllowNotifyCSRRejected"
:error-messages="
form().serverErrors(
@@ -1095,16 +1095,16 @@
></v-checkbox>
</v-col>
<v-col
v-if="obj.customerAllowNotifyCSRRejected"
cols="12"
sm="6"
lg="9"
v-if="obj.customerAllowNotifyCSRRejected"
>
<gz-tag-picker
ref="customerAllowNotifyCSRRejectedInTags"
v-model="obj.customerAllowNotifyCSRRejectedInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowNotifyCSRRejectedInTags"
data-cy="customerAllowNotifyCSRRejectedInTags"
:error-messages="
form().serverErrors(
@@ -1124,10 +1124,10 @@
<v-col cols="12" sm="6" lg="3">
<v-checkbox
ref="customerAllowNotifyWOCreated"
v-model="obj.customerAllowNotifyWOCreated"
:readonly="formState.readOnly"
:label="$ay.t('NotifyEventWorkorderCreatedForCustomer')"
ref="customerAllowNotifyWOCreated"
data-cy="customerAllowNotifyWOCreated"
:error-messages="
form().serverErrors(
@@ -1141,16 +1141,16 @@
></v-checkbox>
</v-col>
<v-col
v-if="obj.customerAllowNotifyWOCreated"
cols="12"
sm="6"
lg="9"
v-if="obj.customerAllowNotifyWOCreated"
>
<gz-tag-picker
ref="customerAllowNotifyWOCreatedInTags"
v-model="obj.customerAllowNotifyWOCreatedInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowNotifyWOCreatedInTags"
data-cy="customerAllowNotifyWOCreatedInTags"
:error-messages="
form().serverErrors(
@@ -1170,10 +1170,10 @@
<v-col cols="12" sm="6" lg="3">
<v-checkbox
ref="customerAllowNotifyWOCompleted"
v-model="obj.customerAllowNotifyWOCompleted"
:readonly="formState.readOnly"
:label="$ay.t('NotifyEventWorkorderCompleted')"
ref="customerAllowNotifyWOCompleted"
data-cy="customerAllowNotifyWOCompleted"
:error-messages="
form().serverErrors(
@@ -1187,16 +1187,16 @@
></v-checkbox>
</v-col>
<v-col
v-if="obj.customerAllowNotifyWOCompleted"
cols="12"
sm="6"
lg="9"
v-if="obj.customerAllowNotifyWOCompleted"
>
<gz-tag-picker
ref="customerAllowNotifyWOCompletedInTags"
v-model="obj.customerAllowNotifyWOCompletedInTags"
:readonly="formState.readOnly"
:label="$ay.t('ContactCustomerHeadOfficeTaggedWith')"
ref="customerAllowNotifyWOCompletedInTags"
data-cy="customerAllowNotifyWOCompletedInTags"
:error-messages="
form().serverErrors(
@@ -1229,51 +1229,6 @@
const FORM_KEY = "global-settings-edit";
const API_BASE_URL = "global-biz-setting/";
export default {
async created() {
const vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.Global);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: slightly different in this form as there is only ever a single global object so no need for a bunch of code
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
window.$gz.form.setFormState({
vm: vm,
loading: false
});
} else {
await vm.getDataFromApi();
}
window.$gz.form.setFormState({
vm: vm,
dirty: false,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
obj: {
@@ -1357,6 +1312,51 @@ export default {
deep: true
}
},
async created() {
const vm = this;
try {
await initForm();
vm.rights = window.$gz.role.getRights(window.$gz.type.Global);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//NOTE: slightly different in this form as there is only ever a single global object so no need for a bunch of code
//is there already an obj from a prior operation?
if (this.$route.params.obj) {
//yes, no need to fetch it
this.obj = this.$route.params.obj;
window.$gz.form.setFormState({
vm: vm,
loading: false
});
} else {
await vm.getDataFromApi();
}
window.$gz.form.setFormState({
vm: vm,
dirty: false,
valid: true
});
generateMenu(vm);
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
vm.formState.ready = true;
}
},
async beforeRouteLeave(to, from, next) {
if (!this.formState.dirty) {
next();
return;
}
if ((await window.$gz.dialog.confirmLeaveUnsaved()) === true) {
next();
} else {
next(false);
}
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
methods: {
canSave: function() {
return this.formState.valid && this.formState.dirty;
@@ -1507,15 +1507,15 @@ function generateMenu(vm) {
/////////////////////////////////
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
async function initForm() {
await fetchTranslatedText();
}
//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
async function fetchTranslatedText() {
await window.$gz.translation.cacheTranslations([
"DefaultReport",
"ContactCustomerHeadOfficeTaggedWith",

Some files were not shown because too many files have changed in this diff Show More