This commit is contained in:
2021-04-13 23:18:03 +00:00
parent a2551951b7
commit 95aff8d755
2 changed files with 103 additions and 59 deletions

View File

@@ -228,7 +228,6 @@ todo: many biz objects are not using new PUT methodology
CURRENTLY DOING: CURRENTLY DOING:
OVERALL OVERALL
- Duplicate test
- Partial save even if parts fail?? - Partial save even if parts fail??
kind of the point of the new system isn't it? kind of the point of the new system isn't it?
or was that to allow a user to go into a specific section and edit it, not necessarily make willy nilly edits anywhere or was that to allow a user to go into a specific section and edit it, not necessarily make willy nilly edits anywhere

View File

@@ -413,64 +413,92 @@ export default {
//walk the tree and save dirty //walk the tree and save dirty
//items in correct order //items in correct order
//######################################################## //########################################################
let noProblem = true;
const isPost = vm.obj.id == 0; const isPost = vm.obj.id == 0;
let err = {
fatal: false, //fatal error, further save is pointless, bail early and report
error: false, //true if any error regardless if fatal, set by each save / delete
header: null, //res.error collections exactly as provided by server to be synthesized later
states: [],
items: [],
scheduledUsers: []
};
/*
TODO: collect return errors but continue to try to save unless fatal error then bail
report cumulative errors at end as if a single save
- return object with format: {fatalError:true/false, errors:[collection of errors ]}
*/
//UNSAVED HEADER MUST BE FIRST //UNSAVED HEADER MUST BE FIRST
//(otherwise there's nothing to hang the other things off of) //(otherwise there's nothing to hang the other things off of)
let headerSaved = false; let headerSaved = false;
if (this.obj.concurrency == 0) { if (this.obj.concurrency == 0) {
noProblem = await saveHeader(vm); err = await saveHeader(vm, err);
headerSaved = true; headerSaved = true;
} }
//LOCKED? State must be saved first then (assuming it unlocks) //LOCKED? State must be saved first then (assuming it unlocks)
let stateSaved = false; let stateSaved = false;
if (this.obj.isLockedAtServer) { if (this.obj.isLockedAtServer) {
noProblem = await saveState(vm); err = await saveState(vm, err);
stateSaved = true; if (!err.fatal) {
//update which areas are available to user stateSaved = true;
//which may have changed due to state being saved (saveState sets the current islocked value) //update which areas are available to user
updateRights(vm); //which may have changed due to state being saved (saveState sets the current islocked value)
updateRights(vm);
}
} }
//############# DELETE GRAPH ############### //############# DELETE GRAPH ###############
//NOTE: Plan is delete from bottom up //NOTE: Plan is delete from bottom up
//SCHEDULED USERS //SCHEDULED USERS
if (noProblem) { if (!err.fatal) {
noProblem = await deleteScheduledUsers(vm); err = await deleteScheduledUsers(vm, err);
} }
//todo: other grandchildren //todo: other grandchildren
//WOITEMS //WOITEMS
if (noProblem) { if (!err.fatal) {
noProblem = await deleteItems(vm); err = await deleteItems(vm, err);
} }
//############ SAVE GRAPH ############### //############ SAVE GRAPH ###############
//NOTE: Plan is save from top down //NOTE: Plan is save from top down
//HEADER //HEADER
if (noProblem && !headerSaved) { if (!err.fata && !headerSaved) {
noProblem = await saveHeader(vm); err = await saveHeader(vm, err);
} }
//WOITEMS //WOITEMS
if (noProblem) { if (!err.fatal) {
//This saves all bottom level collections as well //This saves all bottom level collections as well
noProblem = await saveItems(vm); err = await saveItems(vm, err);
} }
//### STATE last normally //### STATE last normally
//in case it locks or is completed //in case it locks or is completed
if (!stateSaved && noProblem) { if (!err.fatal && !stateSaved) {
noProblem = await saveState(vm); err = await saveState(vm, err);
updateRights(vm); if (!err.fatal) {
updateRights(vm);
}
} }
//## ALL PARTIAL UPDATES SUCCEEDED //## ALL PARTIAL UPDATES COMPLETED
if (!noProblem) { //todo: walk the err object extract errors and set for display HERE regardless if fatal or not
//this assumes error is already displayed from save op //todo: how to proceed?
//if it's a post and partially successful then what?
//samesies, if the post partially succeeded that means at least the header succeeded because nothing else would
//so nothing need be done other than route will show weird (0) in address bar, but object is consistent since
//the concurrency and id would be set on the header
//if its' an update easier to just display and bail otu
if (err.fatal) {
//save failed fataly so just set the state and bail out
window.$gz.form.setFormState({ window.$gz.form.setFormState({
vm: vm, vm: vm,
dirty: true, dirty: true,
@@ -593,9 +621,9 @@ export default {
///////////////////////////// /////////////////////////////
// HEADER // HEADER
// //
async function saveHeader(vm) { async function saveHeader(vm, err) {
if (!vm.obj.isDirty) { if (!vm.obj.isDirty) {
return true; return err;
} }
const isPost = vm.obj.id == 0; const isPost = vm.obj.id == 0;
@@ -606,8 +634,12 @@ async function saveHeader(vm) {
let res = await window.$gz.api.upsert(`${API_BASE_URL}`, headerOnly); let res = await window.$gz.api.upsert(`${API_BASE_URL}`, headerOnly);
if (res.error) { if (res.error) {
displayResError(vm, res); if (isPost) {
return false; err.fatal = true;
}
err.header = res.error;
err.error = true;
return err;
} else { } else {
//update any server changed fields //update any server changed fields
vm.obj.concurrency = res.data.concurrency; vm.obj.concurrency = res.data.concurrency;
@@ -619,18 +651,18 @@ async function saveHeader(vm) {
vm.obj.states.forEach(z => (z.workOrderId = vm.obj.id)); vm.obj.states.forEach(z => (z.workOrderId = vm.obj.id));
vm.obj.items.forEach(z => (z.workOrderId = vm.obj.id)); vm.obj.items.forEach(z => (z.workOrderId = vm.obj.id));
} }
return true; return err;
} }
} }
///////////////////////////// /////////////////////////////
// STATES // STATES
// //
async function saveState(vm) { async function saveState(vm, err) {
//CHANGED? //CHANGED?
let totalItems = vm.obj.states.length; let totalItems = vm.obj.states.length;
if (totalItems == 0) { if (totalItems == 0) {
return true; return err;
} }
for (let i = 0; i < totalItems; i++) { for (let i = 0; i < totalItems; i++) {
let o = vm.obj.states[i]; let o = vm.obj.states[i];
@@ -638,8 +670,8 @@ async function saveState(vm) {
//it's new so save it //it's new so save it
let res = await window.$gz.api.upsert(`${API_BASE_URL}states`, o); let res = await window.$gz.api.upsert(`${API_BASE_URL}states`, o);
if (res.error) { if (res.error) {
displayResError(vm, res); err.states.push(res.error);
return false; err.error = true;
} else { } else {
vm.obj.states[i] = res.data; vm.obj.states[i] = res.data;
@@ -648,25 +680,29 @@ async function saveState(vm) {
} }
} }
} }
return true; return err;
} }
///////////////////////////// /////////////////////////////
// ITEMS // ITEMS
// //
async function deleteItems(vm) { async function deleteItems(vm, err) {
while (vm.deletedGraphItems.items.length) { if (vm.deletedGraphItems.items.length == 0) {
return err;
}
//walk the array backwards as items may or may not be spliced out
for (var i = vm.deletedGraphItems.items.length - 1; i >= 0; i--) {
let res = await window.$gz.api.remove( let res = await window.$gz.api.remove(
`${API_BASE_URL}items/${vm.deletedGraphItems.items[0]}` `${API_BASE_URL}items/${vm.deletedGraphItems.items[0]}`
); );
if (res.error) { if (res.error) {
displayResError(vm, res); err.items.push(res.error);
return false; err.error = true;
} else { } else {
vm.deletedGraphItems.items.splice(0, 1); vm.deletedGraphItems.items.splice(i, 1);
} }
return err;
} }
return true;
} }
async function saveItems(vm) { async function saveItems(vm) {
let totalItems = vm.obj.items.length; let totalItems = vm.obj.items.length;
@@ -693,10 +729,16 @@ async function saveItems(vm) {
const isPost = o.id == 0; const isPost = o.id == 0;
let res = await window.$gz.api.upsert(`${API_BASE_URL}items`, o); let res = await window.$gz.api.upsert(`${API_BASE_URL}items`, o);
if (res.error) { if (res.error) {
displayResError(vm, res); err.items.push(res.error);
return false; err.error = true;
if (isPost) {
//a post error precludes further operations on this item below
//however, an update error doesn't necessarily because it's still a existing workorder item
//so it's children can probably be updated and we want that
continue;
}
} else { } else {
//update any server changed fields //no error so update any server changed fields
//put fields //put fields
vm.obj.items[i].concurrency = res.data.concurrency; vm.obj.items[i].concurrency = res.data.concurrency;
vm.obj.items[i].isDirty = false; vm.obj.items[i].isDirty = false;
@@ -717,13 +759,14 @@ async function saveItems(vm) {
} }
//------ //------
//save grandchildren //save grandchildren
if (!(await saveScheduledUsers(vm, i))) { err = await saveScheduledUsers(vm, i.err);
return false; if (err.fatal) {
return err;
} }
//todo: other grandchildren
//------ //------
// console.log("Bottom of items loop", { totalItems: totalItems, i: i });
} }
return true; //made it through return err; //made it through
} }
//#################################################################################### //####################################################################################
//## GRANDCHILDREN //## GRANDCHILDREN
@@ -731,19 +774,21 @@ async function saveItems(vm) {
///////////////////////////// /////////////////////////////
// SCHEDULED USERS // SCHEDULED USERS
// //
async function deleteScheduledUsers(vm) { async function deleteScheduledUsers(vm, err) {
while (vm.deletedGraphItems.scheduledUsers.length) { //walk the array backwards as items may or may not be spliced out
for (var i = vm.deletedGraphItems.scheduledUsers.length - 1; i >= 0; i--) {
// while (vm.deletedGraphItems.scheduledUsers.length) {
let res = await window.$gz.api.remove( let res = await window.$gz.api.remove(
`${API_BASE_URL}items/scheduledusers/${vm.deletedGraphItems.scheduledUsers[0]}` `${API_BASE_URL}items/scheduledusers/${vm.deletedGraphItems.scheduledUsers[0]}`
); );
if (res.error) { if (res.error) {
displayResError(vm, res); err.items.push(res.error);
return false; err.error = true;
} else { } else {
vm.deletedGraphItems.scheduledUsers.splice(0, 1); vm.deletedGraphItems.scheduledUsers.splice(i, 1);
} }
} }
return true; return err;
} }
async function saveScheduledUsers(vm, woitemindex) { async function saveScheduledUsers(vm, woitemindex) {
@@ -781,14 +826,14 @@ async function saveScheduledUsers(vm, woitemindex) {
//todo: other grandchildren //todo: other grandchildren
///////////////////////////// // /////////////////////////////
// Error display // // Error display
// // //
function displayResError(vm, res) { // function displayResError(vm, res) {
console.log("DISPLAY RES ERROR: ", res); // console.log("DISPLAY RES ERROR: ", res);
vm.formState.serverError = res.error; // vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm); // window.$gz.form.setErrorBoxErrors(vm);
} // }
//######################################### UTILITY METHODS ########################################### //######################################### UTILITY METHODS ###########################################
///////////////////////////// /////////////////////////////