This commit is contained in:
2021-04-16 20:08:39 +00:00
parent 948f79e4df
commit ea4fc8edae
3 changed files with 165 additions and 142 deletions

View File

@@ -230,6 +230,8 @@ CURRENTLY DOING: save (and delete), then error handling (move to individual save
OVERALL OVERALL
ORDERING AND ERRORS ORDERING AND ERRORS
- WOITEMS NEED A GUARANTEED GOOD INDEX apart from all others
uiindex temporary value guaranteed to be unique (timestamp?)
- if woitem is flagged for delete all children should be as well - if woitem is flagged for delete all children should be as well
just flag them in the tree when the woitem is flagged toggle children just flag them in the tree when the woitem is flagged toggle children
- SOFT DELETE ISSUE: - SOFT DELETE ISSUE:

View File

@@ -165,6 +165,7 @@ export default {
methods: { methods: {
newItem() { newItem() {
let newIndex = this.value.items.length; let newIndex = this.value.items.length;
this.value.items.push({ this.value.items.push({
id: 0, id: 0,
concurrency: 0, concurrency: 0,
@@ -189,7 +190,8 @@ export default {
tasks: [], tasks: [],
travels: [], travels: [],
units: [], units: [],
outsideServices: [] outsideServices: [],
uid: Date.now() //guaranteed unique and higher than any prior
}); });
this.$emit("change"); this.$emit("change");
this.selectedRow = [{ index: newIndex }]; this.selectedRow = [{ index: newIndex }];

View File

@@ -245,9 +245,9 @@ export default {
delete: true delete: true
} }
}, },
saveError: { saveResult: {
fatal: false, //fatal error, further save is pointless, bail early and report fatal: false, //fatal error, further save is pointless, bail early and report
error: null //contains error object errors: null //contains error objects from save
} }
}; };
}, },
@@ -357,6 +357,9 @@ export default {
window.$gz.form.setErrorBoxErrors(vm); window.$gz.form.setErrorBoxErrors(vm);
} else { } else {
vm.obj = res.data; vm.obj = res.data;
vm.obj.items.forEach((z, index) => (z.uid = index));
console.log("getdata items indexed:", vm.obj.items);
//modify the menu as necessary //modify the menu as necessary
generateMenu(vm); generateMenu(vm);
//update which areas are available to user //update which areas are available to user
@@ -413,8 +416,8 @@ export default {
const isPost = vm.obj.id == 0; const isPost = vm.obj.id == 0;
//reset error object //reset error object
this.saveError.fatal = false; this.saveResult.fatal = false;
this.saveError.error = null; this.saveResult.errors = null;
/* /*
@@ -446,7 +449,7 @@ export default {
let stateSaved = false; let stateSaved = false;
if (this.obj.isLockedAtServer) { if (this.obj.isLockedAtServer) {
await saveState(vm); await saveState(vm);
if (!this.saveError.fatal) { if (!this.saveResult.fatal) {
stateSaved = true; stateSaved = true;
//update which areas are available to user //update which areas are available to user
//which may have changed due to state being saved (saveState sets the current islocked value) //which may have changed due to state being saved (saveState sets the current islocked value)
@@ -455,115 +458,37 @@ export default {
} }
//HEADER //HEADER
if (!this.saveError.fatal && !headerSaved) { if (!this.saveResult.fatal && !headerSaved) {
await saveHeader(vm); await saveHeader(vm);
} }
//WOITEMS //WOITEMS
if (!this.saveError.fatal) { if (!this.saveResult.fatal) {
//first sort items into sequence order so that the errors line up with the display
this.obj.items.sort((a, b) => a.sequence - b.sequence);
//This saves all bottom level collections as well //This saves all bottom level collections as well
await saveItems(vm); await saveItems(vm);
} }
//### STATE last normally //### STATE last normally
//in case it locks or is completed //in case it locks or is completed
if (!this.saveError.fatal && !stateSaved) { if (!this.saveResult.fatal && !stateSaved) {
await saveState(vm); await saveState(vm);
if (!this.saveError.fatal) { if (!this.saveResult.fatal) {
updateRights(vm); updateRights(vm);
} }
} }
//## ALL PARTIAL UPDATES COMPLETED //## ALL PARTIAL UPDATES COMPLETED
//handle errors //handle errors
if (this.saveError.error != null) { if (this.saveResult.errors != null) {
//# FAIL ROUTE //# FAIL ROUTE
//##### TODO: Move error compilation into saves, no need for this complex rigamarole vm.formState.serverError = formErrorFromSaveResult();
//bugbug: details is an array inside so there could be multiple errors for that target so need to iterate it inside the iteration
//bugbug: on a server error there is no details so dont' code to expect it
/*i.e.
{
error: {
code: "2002",
message: "See server log for details",
target: "Server internal error"
}
}
*/
//wouldn't this just be easier to do directly inside the saves themselves??
//why compile it at all, why not make it directly ready to display at the end, there's no other use for this info really
vm.formState.serverError = this.saveError.error;
window.$gz.form.setErrorBoxErrors(vm); window.$gz.form.setErrorBoxErrors(vm);
/*
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
{
"fatal": false,
"error": true,
"header": null,
"states": [],
"items": [
{
"e": {
"code": "2200",
"details": [
{
"message": "SAVE TEST ERROR",
"target": "Notes",
"error": "2203"
}
],
"message": "ErrorAPI2200"
},
"objectIndex": 2
}
],
"scheduledUsers": [
{
"e": {
"code": "2200",
"details": [
{
"message": "◈◈ TEST SAVE ERROR ◈◈",
"target": "EstimatedQuantity",
"error": "2203"
}
],
"message": "ErrorAPI2200"
},
"objectIndex": 0,
"woItemIndex": 3
}
]
}
DESTINATION FORMAT EXAMPLE:
error: {
code: "2200",
details: [
{
message:
"LT:PurchaseOrderReceiptItemQuantityReceivedErrorInvalid",
target: "Items[1].QuantityReceived",
error: "2203"
},
{
message:
"LT:PurchaseOrderReceiptItemQuantityReceivedErrorInvalid",
target: "Items[3].QuantityReceived",
error: "2203"
}
],
message: "ErrorAPI2200"
}
}
*/
//TODO: If it's a fatal error set accordingly and bail out here //TODO: If it's a fatal error set accordingly and bail out here
// if (err.fatal) { // if (err.fatal) {
@@ -747,50 +672,12 @@ async function saveState(vm) {
} }
} }
} }
function handleSaveError(e) {
/*
e:{
fatal:true/false,//override, normally this function would determine this on it's own
error:res.error,//server error
itemIndex:null,//if has parent woitem this is where it's index is set
childKey:"scheduledUsers"/"Items",//name of child collection
childIndex:null,//if it's a child this is the index
}
//old compiledError code
err.items.forEach(z =>
compiledError.details.push({
message: z.e.details[0].message,
error: z.e.details[0].error,
target: `Items[${z.objectIndex}].${z.e.details[0].target}`
})
);
err.scheduledUsers.forEach(z =>
compiledError.details.push({
message: z.e.details[0].message,
error: z.e.details[0].error,
target: `Items[${z.woItemIndex}].scheduledUsers[${z.objectIndex}].${z.e.details[0].target}`
})
);
//Goes into this.saveError.error ultimately
saveError: {
fatal: false, //fatal error, further save is pointless, bail early and report
error: null //contains error object
}
*/
if (this.error == null) {
this.error = [];
}
//set Target properly as requried and push error into the error collection
}
///////////////////////////// /////////////////////////////
// ITEMS // ITEMS
// //
async function deleteItems(vm) { async function deleteItems(vm) {
//TODO: MUST OPERATE IN SEQUENCE ORDER TO MATCH VIEW
//walk the array backwards as items may or may not be spliced out //walk the array backwards as items may or may not be spliced out
for (var i = vm.obj.items.length - 1; i >= 0; i--) { for (var i = vm.obj.items.length - 1; i >= 0; i--) {
const d = vm.obj.items[i]; const d = vm.obj.items[i];
@@ -799,13 +686,7 @@ async function deleteItems(vm) {
} }
let res = await window.$gz.api.remove(`${API_BASE_URL}items/${d.id}`); let res = await window.$gz.api.remove(`${API_BASE_URL}items/${d.id}`);
if (res.error) { if (res.error) {
handleSaveError(res.error, true); handleSaveError({ fatal: true, error: res.error, itemIndex: i });
err.items.push({
e: res.error,
objectIndex: d.objectIndex,
woItemIndex: d.woItemIndex
});
err.error = true;
} else { } else {
vm.obj.items.splice(i, 1); vm.obj.items.splice(i, 1);
} }
@@ -821,6 +702,7 @@ async function saveItems(vm, err) {
} }
//SAVE WOITEMS //SAVE WOITEMS
//TODO: MUST OPERATE IN SEQUENCE ORDER TO MATCH VIEW
for (let i = 0; i < vm.obj.items.length; i++) { for (let i = 0; i < vm.obj.items.length; i++) {
//get copy of item without child collections for independant submit //get copy of item without child collections for independant submit
const { const {
@@ -840,8 +722,7 @@ async function saveItems(vm, err) {
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) {
err.items.push({ e: res.error, objectIndex: i }); handleSaveError({ error: res.error, itemIndex: i });
err.error = true;
if (isPost) { if (isPost) {
//a post error precludes further operations on this item below //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 //however, an update error doesn't necessarily because it's still a existing workorder item
@@ -885,7 +766,7 @@ async function saveItems(vm, err) {
///////////////////////////// /////////////////////////////
// SCHEDULED USERS // SCHEDULED USERS
// //
async function deleteScheduledUsers(vm, woItemIndex, err) { async function deleteScheduledUsers(vm, woItemIndex) {
//walk the array backwards as items may be spliced out //walk the array backwards as items may be spliced out
for ( for (
var i = vm.obj.items[woItemIndex].scheduledUsers.length - 1; var i = vm.obj.items[woItemIndex].scheduledUsers.length - 1;
@@ -900,6 +781,13 @@ async function deleteScheduledUsers(vm, woItemIndex, err) {
`${API_BASE_URL}items/scheduledusers/${d.id}` `${API_BASE_URL}items/scheduledusers/${d.id}`
); );
if (res.error) { if (res.error) {
handleSaveError({
error: res.error,
itemIndex: woItemIndex,
childKey: "scheduledUsers",
childIndex: i
});
err.scheduledUsers.push({ err.scheduledUsers.push({
e: res.error, e: res.error,
objectIndex: d.objectIndex, objectIndex: d.objectIndex,
@@ -957,6 +845,137 @@ async function saveScheduledUsers(vm, woItemIndex, err) {
//todo: other grandchildren //todo: other grandchildren
//######################################### UTILITY METHODS ########################################### //######################################### UTILITY METHODS ###########################################
function handleSaveError(e) {
//TODO: decide if fatal here and set accordingly
if (this.errors == null) {
this.errors = [];
}
this.errors.push(e);
}
function formErrorFromSaveResult() {
//digest saveresult and compile into standard form error and return
/*
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
{
"fatal": false,
"error": true,
"header": null,
"states": [],
"items": [
{
"e": {
"code": "2200",
"details": [
{
"message": "SAVE TEST ERROR",
"target": "Notes",
"error": "2203"
}
],
"message": "ErrorAPI2200"
},
"objectIndex": 2
}
],
"scheduledUsers": [
{
"e": {
"code": "2200",
"details": [
{
"message": "◈◈ TEST SAVE ERROR ◈◈",
"target": "EstimatedQuantity",
"error": "2203"
}
],
"message": "ErrorAPI2200"
},
"objectIndex": 0,
"woItemIndex": 3
}
]
}
DESTINATION FORMAT EXAMPLE:
error: {
code: "2200",
details: [
{
message:
"LT:PurchaseOrderReceiptItemQuantityReceivedErrorInvalid",
target: "Items[1].QuantityReceived",
error: "2203"
},
{
message:
"LT:PurchaseOrderReceiptItemQuantityReceivedErrorInvalid",
target: "Items[3].QuantityReceived",
error: "2203"
}
],
message: "ErrorAPI2200"
}
}
e:{
fatal:true/false,//override, normally this function would determine this on it's own
error:res.error,//server error
itemUid:null,//if has parent woitem this is its UID which is used to determine actual index
childKey:"scheduledUsers"/"Items",//name of child collection
childIndex:null,//if it's a child this is the index
}
//old compiledError code
err.items.forEach(z =>
compiledError.details.push({
message: z.e.details[0].message,
error: z.e.details[0].error,
target: `Items[${z.objectIndex}].${z.e.details[0].target}`
})
);
err.scheduledUsers.forEach(z =>
compiledError.details.push({
message: z.e.details[0].message,
error: z.e.details[0].error,
target: `Items[${z.woItemIndex}].scheduledUsers[${z.objectIndex}].${z.e.details[0].target}`
})
);
//Goes into this.saveResult.errors ultimately
saveResult: {
fatal: false, //fatal error, further save is pointless, bail early and report
error: null //contains error object
}
//bugbug: details is an array inside so there could be multiple errors for that target so need to iterate it inside the iteration
//bugbug: on a server error there is no details so dont' code to expect it
/*i.e.
{
error: {
code: "2002",
message: "See server log for details",
target: "Server internal error"
}
}
*/
//TODO: compile is back on the menu
//iterate saveresult errors and hydrate into a displayable error as expected
//(deal with translate uid's to woitem indexes that still exist)
*/
////set Target properly as requried and push error into the error collection
// this.saveResult.errors;
}
///////////////////////////// /////////////////////////////
// //
// //