This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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 }];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
//
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user