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
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
just flag them in the tree when the woitem is flagged toggle children
- SOFT DELETE ISSUE:

View File

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

View File

@@ -245,9 +245,9 @@ export default {
delete: true
}
},
saveError: {
saveResult: {
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);
} else {
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
generateMenu(vm);
//update which areas are available to user
@@ -413,8 +416,8 @@ export default {
const isPost = vm.obj.id == 0;
//reset error object
this.saveError.fatal = false;
this.saveError.error = null;
this.saveResult.fatal = false;
this.saveResult.errors = null;
/*
@@ -446,7 +449,7 @@ export default {
let stateSaved = false;
if (this.obj.isLockedAtServer) {
await saveState(vm);
if (!this.saveError.fatal) {
if (!this.saveResult.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)
@@ -455,115 +458,37 @@ export default {
}
//HEADER
if (!this.saveError.fatal && !headerSaved) {
if (!this.saveResult.fatal && !headerSaved) {
await saveHeader(vm);
}
//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
await saveItems(vm);
}
//### STATE last normally
//in case it locks or is completed
if (!this.saveError.fatal && !stateSaved) {
if (!this.saveResult.fatal && !stateSaved) {
await saveState(vm);
if (!this.saveError.fatal) {
if (!this.saveResult.fatal) {
updateRights(vm);
}
}
//## ALL PARTIAL UPDATES COMPLETED
//handle errors
if (this.saveError.error != null) {
if (this.saveResult.errors != null) {
//# FAIL ROUTE
//##### TODO: Move error compilation into saves, no need for this complex rigamarole
//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;
vm.formState.serverError = formErrorFromSaveResult();
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
// 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
//
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
for (var i = vm.obj.items.length - 1; i >= 0; 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}`);
if (res.error) {
handleSaveError(res.error, true);
err.items.push({
e: res.error,
objectIndex: d.objectIndex,
woItemIndex: d.woItemIndex
});
err.error = true;
handleSaveError({ fatal: true, error: res.error, itemIndex: i });
} else {
vm.obj.items.splice(i, 1);
}
@@ -821,6 +702,7 @@ async function saveItems(vm, err) {
}
//SAVE WOITEMS
//TODO: MUST OPERATE IN SEQUENCE ORDER TO MATCH VIEW
for (let i = 0; i < vm.obj.items.length; i++) {
//get copy of item without child collections for independant submit
const {
@@ -840,8 +722,7 @@ async function saveItems(vm, err) {
const isPost = o.id == 0;
let res = await window.$gz.api.upsert(`${API_BASE_URL}items`, o);
if (res.error) {
err.items.push({ e: res.error, objectIndex: i });
err.error = true;
handleSaveError({ error: res.error, itemIndex: i });
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
@@ -885,7 +766,7 @@ async function saveItems(vm, err) {
/////////////////////////////
// SCHEDULED USERS
//
async function deleteScheduledUsers(vm, woItemIndex, err) {
async function deleteScheduledUsers(vm, woItemIndex) {
//walk the array backwards as items may be spliced out
for (
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}`
);
if (res.error) {
handleSaveError({
error: res.error,
itemIndex: woItemIndex,
childKey: "scheduledUsers",
childIndex: i
});
err.scheduledUsers.push({
e: res.error,
objectIndex: d.objectIndex,
@@ -957,6 +845,137 @@ async function saveScheduledUsers(vm, woItemIndex, err) {
//todo: other grandchildren
//######################################### 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;
}
/////////////////////////////
//
//