This commit is contained in:
2020-12-30 17:02:40 +00:00
parent 13436fc68a
commit 07ff575ad0
9 changed files with 1169 additions and 6 deletions

View File

@@ -16,9 +16,9 @@ todo: NEXT DEPLOY TO DEVOPS attach a photo from phone, no error just does nothin
worked here locally latest build worked here locally latest build
retest on server after next deploy retest on server after next deploy
todo: test v8migrate on big shitty database
todo: client gzutil:iconfortype missing all the recent new objects (mostly)
@@ -36,7 +36,7 @@ todo: actual customer reports so can figure out datalist for bringing other name
CURRENTLY DOING: CURRENTLY DOING:
ServiceBank ServiceBank
(note, see cases, has changed, affects client, ho, unit)

View File

@@ -20,6 +20,7 @@ export default {
ServiceRate: { Change: 66, ReadFullRecord: 98701, Select: 131071 }, ServiceRate: { Change: 66, ReadFullRecord: 98701, Select: 131071 },
TravelRate: { Change: 66, ReadFullRecord: 98701, Select: 131071 }, TravelRate: { Change: 66, ReadFullRecord: 98701, Select: 131071 },
TaxCode: { Change: 66, ReadFullRecord: 98701, Select: 131071 }, TaxCode: { Change: 66, ReadFullRecord: 98701, Select: 131071 },
ServiceBank: { Change: 74, ReadFullRecord: 98693, Select: 131071 },
Quote: { Change: 33098, ReadFullRecord: 65669, Select: 131071 }, Quote: { Change: 33098, ReadFullRecord: 65669, Select: 131071 },
QuoteItem: { Change: 33098, ReadFullRecord: 65669, Select: 131071 }, QuoteItem: { Change: 33098, ReadFullRecord: 65669, Select: 131071 },
QuoteTemplate: { Change: 33098, ReadFullRecord: 65669, Select: 131071 }, QuoteTemplate: { Change: 33098, ReadFullRecord: 65669, Select: 131071 },

View File

@@ -458,6 +458,15 @@ function initNavPanel() {
sub = []; sub = [];
if (window.$gz.role.canOpen(window.$gz.type.ServiceBank)) {
sub.push({
title: "ServiceBankList",
icon: "$ayiCarBattery",
route: "/acc-service-banks",
key: key++
});
}
//SERVICE RATES //SERVICE RATES
if (window.$gz.role.canOpen(window.$gz.type.ServiceRate)) { if (window.$gz.role.canOpen(window.$gz.type.ServiceRate)) {
sub.push({ sub.push({

View File

@@ -170,6 +170,7 @@ export default {
"TaxCodeList", "TaxCodeList",
"ServiceRateList", "ServiceRateList",
"TravelRateList", "TravelRateList",
"ServiceBankList",
"Administration", "Administration",
"Operations", "Operations",
"Attachments", "Attachments",

View File

@@ -453,6 +453,18 @@ export default new Router({
component: () => component: () =>
import(/* webpackChunkName: "acc" */ "./views/acc-tax-code.vue") import(/* webpackChunkName: "acc" */ "./views/acc-tax-code.vue")
}, },
{
path: "/acc-service-banks/:objectType?/:objectId?",
name: "service-banks",
component: () =>
import(/* webpackChunkName: "acc" */ "./views/acc-service-banks.vue")
},
{
path: "/acc-service-banks/:recordid/:objectType?/:objectId?",
name: "service-bank-edit",
component: () =>
import(/* webpackChunkName: "acc" */ "./views/acc-service-bank.vue")
},
//######################### ADMINISTRATION GROUP ##################################### //######################### ADMINISTRATION GROUP #####################################
{ {
path: "/adm-global-settings", path: "/adm-global-settings",

View File

@@ -0,0 +1,873 @@
<template>
<v-container fluid>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<div v-if="formState.ready">
<gz-error :errorBoxMessage="formState.errorBoxMessage"></gz-error>
<v-form ref="form">
<div class="mb-6" v-if="obj.objectType">
<v-icon large @click="navToTarget()">{{ iconForType }}</v-icon
><span class="text-h5" @click="navToTarget()"> {{ name }}</span>
</div>
<v-row>
<v-col v-if="currentUserIsASupervisor" cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
:ayaType="ayaTypes().User"
:variant="'inside'"
:showEditIcon="true"
:allowNoSelection="false"
:canClear="false"
v-model="obj.userId"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankUserId')"
:rules="[form().required(this, 'userId')]"
ref="userId"
data-cy="userId"
:error-messages="form().serverErrors(this, 'userId')"
@input="fieldValueChanged('userId')"
></gz-pick-list>
</v-col>
<v-col v-if="currentUserIsASupervisor" cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
:ayaType="ayaTypes().User"
:variant="'inside'"
:showEditIcon="true"
v-model="obj.assignedByUserId"
readonly
:label="$ay.t('ServiceBankAssignedByUserId')"
:rules="[form().required(this, 'assignedByUserId')]"
ref="assignedByUserId"
data-cy="assignedByUserId"
:error-messages="form().serverErrors(this, 'assignedByUserId')"
@input="fieldValueChanged('assignedByUserId')"
></gz-pick-list>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-text-field
v-model="obj.name"
:readonly="
formState.readOnly ||
(!selfAssigned && !currentUserIsASupervisor)
"
:label="$ay.t('ServiceBankName')"
:rules="[form().required(this, 'name')]"
:error-messages="form().serverErrors(this, 'name')"
ref="name"
data-cy="name"
@input="fieldValueChanged('name')"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-date-time-picker
:label="$ay.t('ServiceBankDueDate')"
:rules="[form().required(this, 'dueDate')]"
v-model="obj.dueDate"
:readonly="
formState.readOnly ||
(!selfAssigned && !currentUserIsASupervisor)
"
ref="dueDate"
testId="dueDate"
:error-messages="form().serverErrors(this, 'dueDate')"
@input="fieldValueChanged('dueDate')"
></gz-date-time-picker>
</v-col>
<v-col cols="12">
<v-textarea
v-model="obj.notes"
:readonly="
formState.readOnly ||
(!selfAssigned && !currentUserIsASupervisor)
"
:label="$ay.t('ServiceBankNotes')"
:error-messages="form().serverErrors(this, 'notes')"
ref="notes"
data-cy="notes"
@input="fieldValueChanged('notes')"
auto-grow
></v-textarea>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-date-time-picker
:label="$ay.t('ServiceBankCompletedDate')"
:error-messages="form().serverErrors(this, 'completedDate')"
v-model="obj.completedDate"
:readonly="formState.readOnly"
ref="completedDate"
testId="completedDate"
@input="fieldValueChanged('completedDate')"
></gz-date-time-picker>
</v-col>
<v-col cols="12">
<v-textarea
v-model="obj.completionNotes"
:readonly="formState.readOnly"
:label="$ay.t('ServiceBankCompletionNotes')"
:error-messages="form().serverErrors(this, 'completionNotes')"
ref="completionNotes"
data-cy="completionNotes"
@input="fieldValueChanged('completionNotes')"
auto-grow
></v-textarea>
</v-col>
<!-- --------------------------------- -->
<v-col v-if="form().showMe(this, 'Tags')" cols="12">
<gz-tag-picker
v-model="obj.tags"
:readonly="formState.readOnly"
ref="tags"
data-cy="tags"
:error-messages="form().serverErrors(this, 'tags')"
@input="fieldValueChanged('tags')"
></gz-tag-picker>
</v-col>
<v-col cols="12">
<gz-custom-fields
v-model="obj.customFields"
:formKey="formCustomTemplateKey"
:readonly="formState.readOnly"
:parentVM="this"
ref="customFields"
data-cy="customFields"
:error-messages="form().serverErrors(this, 'customFields')"
@input="fieldValueChanged('customFields')"
></gz-custom-fields>
</v-col>
<v-col v-if="form().showMe(this, 'Wiki')" cols="12">
<gz-wiki
:ayaType="ayaType"
:ayaId="obj.id"
ref="wiki"
v-model="obj.wiki"
:readonly="formState.readOnly"
@input="fieldValueChanged('wiki')"
></gz-wiki
></v-col>
<v-col v-if="form().showMe(this, 'Attachments') && obj.id" cols="12">
<gz-attachments
:readonly="formState.readOnly"
:ayaType="ayaType"
:ayaId="obj.id"
></gz-attachments
></v-col>
</v-row>
</v-form>
</div>
<template v-if="!formState.ready">
<v-progress-circular
indeterminate
color="primary"
:size="60"
></v-progress-circular>
</template>
</v-container>
</template>
<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* Xeslint-disable */
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
const FORM_KEY = "service-bank-edit";
const API_BASE_URL = "service-bank/";
const FORM_CUSTOM_TEMPLATE_KEY = "ServiceBank"; //<-- Should always be CoreBizObject AyaType name here where possible
export default {
async created() {
let vm = this;
try {
await initForm(vm);
vm.rights = window.$gz.role.getRights(window.$gz.type.ServiceBank);
vm.formState.readOnly = !vm.rights.change;
window.$gz.eventBus.$on("menu-click", clickHandler);
//id 0 means create a new record don't load one
if (vm.$route.params.recordid != 0) {
//is there already an obj from a prior operation?
if (vm.$route.params.obj) {
//yes, no need to fetch it
vm.name = vm.$route.params.name;
vm.obj = vm.$route.params.obj;
window.$gz.form.setFormState({
vm: vm,
loading: false
});
} else {
await vm.getDataFromApi(vm.$route.params.recordid); //let getdata handle loading
}
} else {
//New record so there has to be a object type and objectId in route
// path: "/home-service-banks/:recordid/:objectType?/:objectId?",
vm.obj.objectId = window.$gz.util.stringToIntOrNull(
vm.$route.params.objectId
);
vm.obj.objectType = window.$gz.util.stringToIntOrNull(
vm.$route.params.objectType
);
if (!vm.obj.objectId || !vm.obj.objectType) {
throw "ObjectType and ObjectId are required to set a reminder";
}
vm.name = vm.$route.params.name;
window.$gz.form.setFormState({
vm: vm,
loading: false
});
}
if (!vm.name) {
vm.name = await window.$gz.api.fetchBizObjectName(
vm.obj.objectType,
vm.obj.objectId
);
}
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 || 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,
obj:
//IMPORTANT NOTE: Fields that are NON NULLABLE in the schema for the table but *are* hideable **MUST** have a default value set here or else there will be no way to save the record
//I.E. Serial, usertype fields, ACTIVE
//Also, if it's a non-nullable Enum backed field then it should have a valid selection i.e. not zero if there is no zero
//{"data":{"id":2,"concurrency":1257740,"name":"Follow up on this unit","notes":"Additional text about this unit","wiki":null,"customFields":null,"tags":["completed.service-bank","v7-import"],
//"dueDate":"2019-03-21T22:00:00Z","completedDate":"2019-03-21T22:00:00Z","completionNotes":null,"userId":2,"assignedByUserId":1,"objectId":9,"objectType":31,"overDue":false}}
{
id: 0,
concurrency: 0,
name: null,
active: true,
notes: null,
wiki: null,
customFields: "{}",
tags: [],
dueDate: null,
completedDate: null,
completionNotes: null,
userId: window.$gz.store.state.userId,
assignedByUserId: window.$gz.store.state.userId,
objectId: null,
objectType: null,
overDue: false
},
formState: {
ready: false,
dirty: false,
valid: true,
readOnly: false,
loading: true,
errorBoxMessage: null,
appError: null,
serverError: {}
},
rights: window.$gz.role.defaultRightsObject(),
ayaType: window.$gz.type.ServiceBank,
currentUserIsASupervisor: window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull,
window.$gz.role.AUTHORIZATION_ROLES.DispatchFull,
window.$gz.role.AUTHORIZATION_ROLES.InventoryFull,
window.$gz.role.AUTHORIZATION_ROLES.SalesFull,
window.$gz.role.AUTHORIZATION_ROLES.AccountingFull
]),
name: null
};
},
//WATCHERS
watch: {
formState: {
handler: function(val) {
//,oldval is available here too if necessary
if (this.formState.loading) {
return;
}
//enable / disable save button
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");
}
//enable / disable duplicate / new button
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: {
selfAssigned: function() {
return this.obj.userId == this.obj.assignedByUserId;
},
iconForType() {
return window.$gz.util.iconForType(this.obj.objectType);
},
hasSupervisorRole: function() {
//mirrored from ServiceBankBiz.cs validation rule at server
/*
CurrentUserRoles.HasFlag(AuthorizationRoles.BizAdminFull) ||
CurrentUserRoles.HasFlag(AuthorizationRoles.DispatchFull) ||
CurrentUserRoles.HasFlag(AuthorizationRoles.InventoryFull) ||
CurrentUserRoles.HasFlag(AuthorizationRoles.SalesFull) ||
CurrentUserRoles.HasFlag(AuthorizationRoles.AccountingFull);
*/
return window.$gz.role.hasRole([
window.$gz.role.AUTHORIZATION_ROLES.BizAdminFull,
window.$gz.role.AUTHORIZATION_ROLES.DispatchFull,
window.$gz.role.AUTHORIZATION_ROLES.InventoryFull,
window.$gz.role.AUTHORIZATION_ROLES.SalesFull,
window.$gz.role.AUTHORIZATION_ROLES.AccountingFull
]);
}
},
methods: {
navToTarget: function() {
window.$gz.eventBus.$emit("openobject", {
type: this.obj.objectType,
id: this.obj.objectId
});
},
canSave: function() {
return this.formState.valid && this.formState.dirty;
},
canDuplicate: function() {
return this.formState.valid && !this.formState.dirty;
},
ayaTypes: function() {
return window.$gz.type;
},
form() {
return window.$gz.form;
},
fieldValueChanged(ref) {
if (
this.formState.ready &&
!this.formState.loading &&
!this.formState.readOnly
) {
window.$gz.form.fieldValueChanged(this, ref);
}
},
async getDataFromApi(recordId) {
let vm = this;
window.$gz.form.setFormState({
vm: vm,
loading: true
});
if (!recordId) {
throw new Error(FORM_KEY + "::getDataFromApi -> Missing recordID!");
}
let url = API_BASE_URL + recordId;
try {
window.$gz.form.deleteAllErrorBoxErrors(vm);
let res = await window.$gz.api.get(url);
if (res.error) {
//Not found?
if (res.error.code == "2010") {
window.$gz.form.handleObjectNotFound(vm);
}
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
} else {
vm.obj = res.data;
//modify the menu as necessary
generateMenu(vm);
//Update the form status
window.$gz.form.setFormState({
vm: vm,
dirty: false,
valid: true,
loading: false
});
}
} catch (error) {
window.$gz.errorHandler.handleFormError(error, vm);
} finally {
window.$gz.form.setFormState({
vm: vm,
loading: false
});
}
},
async submit() {
let vm = this;
if (vm.canSave == false) {
return;
}
try {
window.$gz.form.setFormState({
vm: vm,
loading: true
});
let url = API_BASE_URL; // + vm.$route.params.recordid;
//clear any errors vm might be around from previous submit
window.$gz.form.deleteAllErrorBoxErrors(vm);
let res = await window.$gz.api.upsert(url, vm.obj);
if (res.error) {
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
} else {
//Logic for detecting if a post or put: if id then it was a post, if no id then it was a put
if (res.data.id) {
//POST - whole new object returned
vm.obj = res.data;
//Change URL to new record
//NOTE: will not cause a page re-render, almost nothing does unless forced with a KEY property or using router.GO()
this.$router.push({
name: "service-bank-edit",
params: {
recordid: res.data.id,
obj: res.data, // Pass data object to new form,
name: this.name
}
});
} else {
//PUT - only concurrency token is returned (**warning, if server changes object other fields then this needs to act more like POST above but is more efficient this way**)
//Handle "put" of an existing record (UPDATE)
vm.obj.concurrency = res.data.concurrency;
}
//Update the form status
window.$gz.form.setFormState({
vm: vm,
dirty: false,
valid: true
});
}
} catch (ex) {
window.$gz.errorHandler.handleFormError(ex, vm);
} finally {
window.$gz.form.setFormState({
vm: vm,
loading: false
});
}
},
async remove() {
let vm = this;
try {
let dialogResult = await window.$gz.dialog.confirmDelete();
if (dialogResult != true) {
return;
}
//do the delete
window.$gz.form.setFormState({
vm: vm,
loading: true
});
//No need to delete a new record, just abandon it...
if (vm.$route.params.recordid == 0) {
//this should not get offered for delete but to be safe and clear just in case:
JUST_DELETED = true;
// navigate backwards
vm.$router.go(-1);
} else {
let url = API_BASE_URL + vm.$route.params.recordid;
window.$gz.form.deleteAllErrorBoxErrors(vm);
let res = await window.$gz.api.remove(url);
if (res.error) {
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
} else {
//workaround to prevent warning about leaving dirty record
//For some reason I couldn't just reset isdirty in formstate
JUST_DELETED = true;
// navigate backwards
vm.$router.go(-1);
}
}
} catch (error) {
//Update the form status
window.$gz.form.setFormState({
vm: vm,
loading: false
});
window.$gz.errorHandler.handleFormError(error, vm);
}
},
async duplicate() {
let vm = this;
if (!vm.canDuplicate || vm.$route.params.recordid == 0) {
return;
}
window.$gz.form.setFormState({
vm: vm,
loading: true
});
let url = API_BASE_URL + "duplicate/" + vm.$route.params.recordid;
try {
window.$gz.form.deleteAllErrorBoxErrors(vm);
let res = await window.$gz.api.upsert(url);
if (res.error) {
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
} else {
//Navigate to new record
this.$router.push({
name: "service-bank-edit",
params: {
recordid: res.data.id,
obj: res.data // Pass data object to new form
}
});
}
} catch (ex) {
window.$gz.errorHandler.handleFormError(ex, vm);
} finally {
window.$gz.form.setFormState({
vm: vm,
loading: false
});
}
},
AddressCopyToPostal() {
let vm = this;
vm.obj.postAddress = vm.obj.address;
vm.obj.postCity = vm.obj.city;
vm.obj.postRegion = vm.obj.region;
vm.obj.postCountry = vm.obj.country;
},
AddressCopyToPhysical() {
let vm = this;
vm.obj.address = vm.obj.postAddress;
vm.obj.city = vm.obj.postCity;
vm.obj.region = vm.obj.postRegion;
vm.obj.country = vm.obj.postCountry;
},
AddressCopyPhysicalToClipBoard() {
let vm = this;
let ret = "";
if (vm.obj.name) {
ret += vm.obj.name + "\n";
}
if (vm.obj.address) {
ret += vm.obj.address + "\n";
}
if (vm.obj.city) {
ret += vm.obj.city + " ";
}
if (vm.obj.region) {
ret += vm.obj.region + " ";
}
if (vm.obj.country) {
ret += vm.obj.country + "\n";
}
window.$gz.util.copyToClipboard(ret);
},
AddressCopyPostalToClipBoard() {
let vm = this;
let ret = "";
if (vm.obj.name) {
ret += vm.obj.name + "\n";
}
if (vm.obj.postAddress) {
ret += vm.obj.postAddress + "\n";
}
if (vm.obj.postCity) {
ret += vm.obj.postCity + " ";
}
if (vm.obj.postRegion) {
ret += vm.obj.postRegion + " ";
}
if (vm.obj.postCode) {
//Postal codes should have two spaces before them according to regs.
ret += " " + vm.obj.postCode + "\n";
}
if (vm.obj.postCountry) {
ret += vm.obj.postCountry + "\n";
}
window.$gz.util.copyToClipboard(ret);
},
async GeoCapture() {
let vm = this;
try {
window.$gz.form.deleteAllErrorBoxErrors(vm);
let loc = await window.$gz.util.getGeoLocation();
vm.obj.latitude = loc.latitude;
vm.fieldValueChanged("latitude");
vm.obj.longitude = loc.longitude;
vm.fieldValueChanged("longitude");
} catch (ex) {
window.$gz.errorHandler.handleFormError(ex, vm);
}
}
//end methods
}
};
/////////////////////////////
//
//
async function clickHandler(menuItem) {
if (!menuItem) {
return;
}
let m = window.$gz.menu.parseMenuItem(menuItem);
if (m.owner == FORM_KEY && !m.disabled) {
switch (m.key) {
case "save":
m.vm.submit();
break;
case "delete":
m.vm.remove();
break;
case "new":
m.vm.$router.push({
name: "service-bank-edit",
params: {
recordid: 0,
objectType: m.vm.obj.objectType,
objectId: m.vm.obj.objectId,
name: m.vm.name
}
});
break;
case "duplicate":
m.vm.duplicate();
break;
case "report":
if (m.id != null) {
//last report selected is in m.id
m.vm.$router.push({
name: "ay-report",
params: { recordid: m.id, ayatype: window.$gz.type.ServiceBank }
});
} else {
//general report selector chosen
let res = await m.vm.$refs.reportSelector.open({
ObjectType: window.$gz.type.ServiceBank,
selectedRowIds: [m.vm.obj.id]
});
//if null for no selection
//just bail out
if (res == null) {
return;
}
//persist last report selected
window.$gz.form.setLastReport(FORM_KEY, res);
//Now open the report viewer...
m.vm.$router.push({
name: "ay-report",
params: { recordid: res.id, ayatype: window.$gz.type.ServiceBank }
});
}
break;
case "geoview":
window.$gz.util.viewGeoLocation({
latitude: m.vm.obj.latitude,
longitude: m.vm.obj.longitude,
address: m.vm.obj.address || m.vm.obj.postAddress,
city: m.vm.obj.city || m.vm.obj.postCity,
region: m.vm.obj.region || m.vm.obj.postRegion,
country: m.vm.obj.country || m.vm.obj.postCountry,
postCode: m.vm.obj.postCode
});
break;
default:
window.$gz.eventBus.$emit(
"notify-warning",
FORM_KEY + "::context click: [" + m.key + "]"
);
}
}
}
//////////////////////
//
//
function generateMenu(vm) {
let menuOptions = {
isMain: false,
readOnly: vm.formState.readOnly,
icon: "$ayiCalendarCheck",
title: "ServiceBank",
helpUrl: "form-home-service-banks",
formData: {
ayaType: window.$gz.type.ServiceBank,
recordId: vm.$route.params.recordid,
formCustomTemplateKey: FORM_CUSTOM_TEMPLATE_KEY
},
menuItems: []
};
if (vm.rights.change) {
menuOptions.menuItems.push({
title: "Save",
icon: "$ayiSave",
surface: true,
key: FORM_KEY + ":save",
vm: vm
});
}
if (vm.rights.delete && vm.$route.params.recordid != 0) {
if (vm.selfAssigned || vm.hasSupervisorRole) {
menuOptions.menuItems.push({
title: "Delete",
icon: "$ayiTrashAlt",
surface: false,
key: FORM_KEY + ":delete",
vm: vm
});
}
}
//REPORTS
//Report not Print, print is a further option
menuOptions.menuItems.push({
title: "Report",
icon: "$ayiFileAlt",
key: FORM_KEY + ":report",
vm: vm
});
//get last report selected
let lastReport = window.$gz.form.getLastReport(FORM_KEY);
if (lastReport != null) {
menuOptions.menuItems.push({
title: lastReport.name,
icon: "$ayiFileAlt",
key: FORM_KEY + ":report:" + lastReport.id,
vm: vm
});
}
if (vm.rights.change) {
menuOptions.menuItems.push({
title: "New",
icon: "$ayiPlus",
key: FORM_KEY + ":new",
vm: vm
});
}
if (vm.rights.change) {
if (vm.selfAssigned || vm.hasSupervisorRole) {
menuOptions.menuItems.push({
title: "Duplicate",
icon: "$ayiClone",
key: FORM_KEY + ":duplicate",
vm: vm
});
}
}
menuOptions.menuItems.push({ divider: true, inset: false });
window.$gz.eventBus.$emit("menu-change", menuOptions);
}
let JUST_DELETED = false;
/////////////////////////////////
//
//
async function initForm(vm) {
await fetchTranslatedText(vm);
await window.$gz.formCustomTemplate.get(FORM_CUSTOM_TEMPLATE_KEY);
}
//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText(vm) {
await window.$gz.translation.cacheTranslations([
"ServiceBank",
"ServiceBankName",
"ServiceBankNotes",
"ServiceBankDueDate",
"ServiceBankCompletedDate",
"ServiceBankCompletionNotes",
"ServiceBankUserId",
"ServiceBankAssignedByUserId",
"ServiceBankCustom1",
"ServiceBankCustom2",
"ServiceBankCustom3",
"ServiceBankCustom4",
"ServiceBankCustom5",
"ServiceBankCustom6",
"ServiceBankCustom7",
"ServiceBankCustom8",
"ServiceBankCustom9",
"ServiceBankCustom10",
"ServiceBankCustom11",
"ServiceBankCustom12",
"ServiceBankCustom13",
"ServiceBankCustom14",
"ServiceBankCustom15",
"ServiceBankCustom16"
]);
}
</script>

View File

@@ -0,0 +1,234 @@
<template>
<div>
<div v-if="objectType && objectId" class="mb-6">
<v-icon @click="navToTarget()" large>{{ iconForType() }}</v-icon
><span @click="navToTarget()" class="text-h5"> {{ name }}</span>
</div>
<gz-report-selector ref="reportSelector"></gz-report-selector>
<gz-extensions
:ayaType="ayType"
:selectedItems="selectedItems"
ref="extensions"
>
</gz-extensions>
<gz-data-table
ref="gzdatatable"
formKey="service-bank-list"
:dataListKey="dataListKey"
:dataListFilter="dataListFilter"
:dataListSort="dataListSort"
:showSelect="rights.read"
:reload="reload"
:metaView="metaView"
v-on:selection-change="handleSelected"
data-cy="service-banksTable"
>
</gz-data-table>
</div>
</template>
<script>
const FORM_KEY = "service-bank-list";
export default {
async created() {
let vm = this;
vm.rights = window.$gz.role.getRights(window.$gz.type.ServiceBank);
window.$gz.eventBus.$on("menu-click", clickHandler);
vm.objectId = window.$gz.util.stringToIntOrNull(vm.$route.params.objectId);
vm.objectType = window.$gz.util.stringToIntOrNull(
vm.$route.params.objectType
);
if (vm.objectId && vm.objectId != 0 && vm.objectType) {
//pre-filter
vm.metaView = JSON.stringify([
{
fld: "metaservicebankobjectid",
filter: {
items: [{ op: "=", value: vm.objectId }]
}
},
{
fld: "AyaType",
filter: {
items: [{ op: "=", value: vm.objectType }]
}
}
]);
vm.name = await window.$gz.api.fetchBizObjectName(
vm.objectType,
vm.objectId
);
}
generateMenu(vm);
},
beforeDestroy() {
window.$gz.eventBus.$off("menu-click", clickHandler);
},
data() {
return {
currentListViewId: 1,
dataListKey: "ServiceBankDataList",
dataListFilter: "",
dataListSort: "",
rights: window.$gz.role.defaultRightsObject(),
ayType: window.$gz.type.ServiceBank,
selectedItems: [],
reload: false,
objectId: null,
objectType: null,
metaView: undefined,
name: null
};
},
// computed: {
// iconForType() {
// return window.$gz.util.iconForType(this.objectType);
// }
// },
methods: {
navToTarget: function() {
window.$gz.eventBus.$emit("openobject", {
type: this.objectType,
id: this.objectId
});
},
handleSelected(selected) {
this.selectedItems = selected;
},
iconForType() {
return window.$gz.util.iconForType(this.objectType, 10);
}
}
};
/////////////////////////////
//
//
async function clickHandler(menuItem) {
if (!menuItem) {
return;
}
let m = window.$gz.menu.parseMenuItem(menuItem);
if (m.owner == FORM_KEY && !m.disabled) {
switch (m.key) {
case "new":
m.vm.$router.push({
name: "service-bank-edit",
params: {
recordid: 0,
objectType: m.vm.objectType,
objectId: m.vm.objectId,
name: m.vm.name
}
});
break;
case "extensions":
let 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":
if (m.id != null) {
//last report selected is in m.id
m.vm.$router.push({
name: "ay-report",
params: { recordid: m.id, ayatype: window.$gz.type.ServiceBank }
});
} else {
//general report selector chosen
let res = await m.vm.$refs.reportSelector.open(
m.vm.$refs.gzdatatable.getDataListSelection(
window.$gz.type.ServiceBank
)
);
//if null for no selection
//just bail out
if (res == null) {
return;
}
//persist last report selected
window.$gz.form.setLastReport(FORM_KEY, res);
//Now open the report viewer...
m.vm.$router.push({
name: "ay-report",
params: { recordid: res.id, ayatype: window.$gz.type.ServiceBank }
});
}
break;
default:
window.$gz.eventBus.$emit(
"notify-warning",
FORM_KEY + "::context click: [" + m.key + "]"
);
}
}
}
//////////////////////
//
//
function generateMenu(vm) {
let menuOptions = {
isMain: true,
icon: "$ayiCarBattery",
title: "ServiceBankList",
helpUrl: "form-acc-service-banks",
menuItems: [],
formData: {
ayaType: window.$gz.type.ServiceBank
}
};
if (vm.rights.change) {
if (vm.objectId && vm.objectType) {
menuOptions.menuItems.push({
title: "New",
icon: "$ayiPlus",
surface: true,
key: FORM_KEY + ":new",
vm: vm
});
}
}
//REPORTS
//Report not Print, print is a further option
menuOptions.menuItems.push({
title: "Report",
icon: "$ayiFileAlt",
key: FORM_KEY + ":report",
vm: vm
});
//get last report selected
let lastReport = window.$gz.form.getLastReport(FORM_KEY);
if (lastReport != null) {
menuOptions.menuItems.push({
title: lastReport.name,
icon: "$ayiFileAlt",
key: FORM_KEY + ":report:" + lastReport.id,
vm: vm
});
}
menuOptions.menuItems.push({
title: "Extensions",
icon: "$ayiPuzzlePiece",
key: FORM_KEY + ":extensions",
vm: vm
});
window.$gz.eventBus.$emit("menu-change", menuOptions);
}
</script>

View File

@@ -311,10 +311,24 @@
data-cy="usesBanking" data-cy="usesBanking"
:error-messages="form().serverErrors(this, 'usesBanking')" :error-messages="form().serverErrors(this, 'usesBanking')"
@change="fieldValueChanged('usesBanking')" @change="fieldValueChanged('usesBanking')"
></v-checkbox> >
<template v-slot:append>
<v-btn
outlined
small
color="primary"
@click="openServiceBank"
class="ml-12"
>
<v-icon>{{ serviceBankIcon() }}</v-icon></v-btn
>
</template>
</v-checkbox>
</v-col> </v-col>
<!-- --------------------------------- --> <!--
--------------------------------- -->
<v-col v-if="form().showMe(this, 'Notes')" cols="12"> <v-col v-if="form().showMe(this, 'Notes')" cols="12">
<v-textarea <v-textarea
v-model="obj.notes" v-model="obj.notes"
@@ -913,6 +927,25 @@ export default {
} }
}, },
methods: { methods: {
serviceBankIcon: function() {
if (this.obj.usesBanking != true || this.$route.params.recordid == 0) {
return null;
}
return "$ayiCarBattery";
},
openServiceBank: function() {
if (this.obj.usesBanking != true || this.$route.params.recordid == 0) {
return null;
}
this.$router.push({
name: "service-banks",
params: {
objectType: window.$gz.type.Customer,
objectId: this.$route.params.recordid
}
});
},
canSave: function() { canSave: function() {
return this.formState.valid && this.formState.dirty; return this.formState.valid && this.formState.dirty;
}, },