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