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:
OVERALL
- Duplicate test
- Partial save even if parts fail??
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

View File

@@ -413,64 +413,92 @@ export default {
//walk the tree and save dirty
//items in correct order
//########################################################
let noProblem = true;
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
//(otherwise there's nothing to hang the other things off of)
let headerSaved = false;
if (this.obj.concurrency == 0) {
noProblem = await saveHeader(vm);
err = await saveHeader(vm, err);
headerSaved = true;
}
//LOCKED? State must be saved first then (assuming it unlocks)
let stateSaved = false;
if (this.obj.isLockedAtServer) {
noProblem = await saveState(vm);
stateSaved = true;
//update which areas are available to user
//which may have changed due to state being saved (saveState sets the current islocked value)
updateRights(vm);
err = await saveState(vm, err);
if (!err.fatal) {
stateSaved = true;
//update which areas are available to user
//which may have changed due to state being saved (saveState sets the current islocked value)
updateRights(vm);
}
}
//############# DELETE GRAPH ###############
//NOTE: Plan is delete from bottom up
//SCHEDULED USERS
if (noProblem) {
noProblem = await deleteScheduledUsers(vm);
if (!err.fatal) {
err = await deleteScheduledUsers(vm, err);
}
//todo: other grandchildren
//WOITEMS
if (noProblem) {
noProblem = await deleteItems(vm);
if (!err.fatal) {
err = await deleteItems(vm, err);
}
//############ SAVE GRAPH ###############
//NOTE: Plan is save from top down
//HEADER
if (noProblem && !headerSaved) {
noProblem = await saveHeader(vm);
if (!err.fata && !headerSaved) {
err = await saveHeader(vm, err);
}
//WOITEMS
if (noProblem) {
if (!err.fatal) {
//This saves all bottom level collections as well
noProblem = await saveItems(vm);
err = await saveItems(vm, err);
}
//### STATE last normally
//in case it locks or is completed
if (!stateSaved && noProblem) {
noProblem = await saveState(vm);
updateRights(vm);
if (!err.fatal && !stateSaved) {
err = await saveState(vm, err);
if (!err.fatal) {
updateRights(vm);
}
}
//## ALL PARTIAL UPDATES SUCCEEDED
if (!noProblem) {
//this assumes error is already displayed from save op
//## ALL PARTIAL UPDATES COMPLETED
//todo: walk the err object extract errors and set for display HERE regardless if fatal or not
//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({
vm: vm,
dirty: true,
@@ -593,9 +621,9 @@ export default {
/////////////////////////////
// HEADER
//
async function saveHeader(vm) {
async function saveHeader(vm, err) {
if (!vm.obj.isDirty) {
return true;
return err;
}
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);
if (res.error) {
displayResError(vm, res);
return false;
if (isPost) {
err.fatal = true;
}
err.header = res.error;
err.error = true;
return err;
} else {
//update any server changed fields
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.items.forEach(z => (z.workOrderId = vm.obj.id));
}
return true;
return err;
}
}
/////////////////////////////
// STATES
//
async function saveState(vm) {
async function saveState(vm, err) {
//CHANGED?
let totalItems = vm.obj.states.length;
if (totalItems == 0) {
return true;
return err;
}
for (let i = 0; i < totalItems; i++) {
let o = vm.obj.states[i];
@@ -638,8 +670,8 @@ async function saveState(vm) {
//it's new so save it
let res = await window.$gz.api.upsert(`${API_BASE_URL}states`, o);
if (res.error) {
displayResError(vm, res);
return false;
err.states.push(res.error);
err.error = true;
} else {
vm.obj.states[i] = res.data;
@@ -648,25 +680,29 @@ async function saveState(vm) {
}
}
}
return true;
return err;
}
/////////////////////////////
// ITEMS
//
async function deleteItems(vm) {
while (vm.deletedGraphItems.items.length) {
async function deleteItems(vm, err) {
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(
`${API_BASE_URL}items/${vm.deletedGraphItems.items[0]}`
);
if (res.error) {
displayResError(vm, res);
return false;
err.items.push(res.error);
err.error = true;
} else {
vm.deletedGraphItems.items.splice(0, 1);
vm.deletedGraphItems.items.splice(i, 1);
}
return err;
}
return true;
}
async function saveItems(vm) {
let totalItems = vm.obj.items.length;
@@ -693,10 +729,16 @@ async function saveItems(vm) {
const isPost = o.id == 0;
let res = await window.$gz.api.upsert(`${API_BASE_URL}items`, o);
if (res.error) {
displayResError(vm, res);
return false;
err.items.push(res.error);
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 {
//update any server changed fields
//no error so update any server changed fields
//put fields
vm.obj.items[i].concurrency = res.data.concurrency;
vm.obj.items[i].isDirty = false;
@@ -717,13 +759,14 @@ async function saveItems(vm) {
}
//------
//save grandchildren
if (!(await saveScheduledUsers(vm, i))) {
return false;
err = await saveScheduledUsers(vm, i.err);
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
@@ -731,19 +774,21 @@ async function saveItems(vm) {
/////////////////////////////
// SCHEDULED USERS
//
async function deleteScheduledUsers(vm) {
while (vm.deletedGraphItems.scheduledUsers.length) {
async function deleteScheduledUsers(vm, err) {
//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(
`${API_BASE_URL}items/scheduledusers/${vm.deletedGraphItems.scheduledUsers[0]}`
);
if (res.error) {
displayResError(vm, res);
return false;
err.items.push(res.error);
err.error = true;
} else {
vm.deletedGraphItems.scheduledUsers.splice(0, 1);
vm.deletedGraphItems.scheduledUsers.splice(i, 1);
}
}
return true;
return err;
}
async function saveScheduledUsers(vm, woitemindex) {
@@ -781,14 +826,14 @@ async function saveScheduledUsers(vm, woitemindex) {
//todo: other grandchildren
/////////////////////////////
// Error display
//
function displayResError(vm, res) {
console.log("DISPLAY RES ERROR: ", res);
vm.formState.serverError = res.error;
window.$gz.form.setErrorBoxErrors(vm);
}
// /////////////////////////////
// // Error display
// //
// function displayResError(vm, res) {
// console.log("DISPLAY RES ERROR: ", res);
// vm.formState.serverError = res.error;
// window.$gz.form.setErrorBoxErrors(vm);
// }
//######################################### UTILITY METHODS ###########################################
/////////////////////////////