diff --git a/ayanova/devdocs/todo.txt b/ayanova/devdocs/todo.txt index 7f66c5c6..617f4d5d 100644 --- a/ayanova/devdocs/todo.txt +++ b/ayanova/devdocs/todo.txt @@ -501,7 +501,9 @@ todo:2 many biz objects are not using new PUT methodology ######################################################################################################################## -CURRENTLY DOING: GetSubsetAsync problem: Non existant keys: QuoteSerialNumber,QuoteStatus +CURRENTLY DOING: generate wo from quote code at svc-workorder::created hook + just try it and then iterate and clean up as necessary until it works, this is the ultimate purpose of the quote really + quote Plan: @@ -518,6 +520,10 @@ Identify cases related to quotes and changes required for quote models particula +todo MISC: + new workorder state set by default from global settings?? (and on generate from pm or quote) + + diff --git a/ayanova/src/views/svc-quote.vue b/ayanova/src/views/svc-quote.vue index 7453c8fe..343b0696 100644 --- a/ayanova/src/views/svc-quote.vue +++ b/ayanova/src/views/svc-quote.vue @@ -87,7 +87,7 @@ export default { //check for copy wo item on route params let wi = this.$route.params.copyItem; if (wi) { - this.washWorkOrderItem(wi); + this.washQuoteItem(wi); wi.quoteId = vm.obj.id; wi.sequence = vm.obj.items.length + 1; vm.obj.items.push(wi); @@ -105,7 +105,7 @@ export default { this.obj.isDirty = true; vm.obj.items.forEach(z => { z.quoteId = 0; - this.washWorkOrderItem(z); + this.washQuoteItem(z); }); setDirty = true; } else { @@ -141,7 +141,7 @@ export default { const goid = Number(this.$route.params.goid); if (gotype != window.$gz.type.Quote) { this.$nextTick(() => { - //not workorder? Then must be a descendant so let's gooooooooooo! + //Then must be a descendant so let's gooooooooooo! this.goto = { type: gotype, id: goid }; }); } @@ -518,10 +518,10 @@ export default { //nav to id'd url //note that an isPost will never be here if there is a fatal error so this is safe to do this.$router.push({ - name: "workorder-edit", + name: "quote-edit", params: { recordid: vm.obj.id - // ,obj: vm.obj // Do NOT Pass data object to new form as normal because for a workorder, it's not a full and complete record at this end + // ,obj: vm.obj // Do NOT Pass data object to new form as normal because for a quote, it's not a full and complete record at this end } }); } else { @@ -602,13 +602,25 @@ export default { duplicate() { //Navigate to new record this.$router.push({ - name: "workorder-edit", + name: "quote-edit", params: { recordid: 0, obj: this.obj } }); }, + generateWorkOrder() { + //Navigate to new record + this.$router.push({ + name: "workorder-edit", + params: { + recordid: 0, + obj: this.obj, + fromQuote: true + } + }); + }, + ///////////////////////////////////////////////////////// // Clean woitem and children so it's // savable as a new record @@ -616,7 +628,7 @@ export default { // also called from quote-items.vue copy woitem when // self target) // - washWorkOrderItem(wi) { + washQuoteItem(wi) { if (wi) { wi.id = 0; wi.concurrency = 0; @@ -731,7 +743,7 @@ async function saveHeader(vm) { if (isPost) { vm.obj.id = res.data.id; vm.obj.serial = res.data.serial; - //walk all unsaved direct children and set the workorder id so they can save + //walk all unsaved direct children and set the id so they can save vm.obj.states.forEach(z => (z.quoteId = vm.obj.id)); vm.obj.items.forEach(z => (z.quoteId = vm.obj.id)); } @@ -814,7 +826,7 @@ async function saveItems(vm) { handleSaveError(vm, { error: res.error, itemUid: o.uid }); 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 + //however, an update error doesn't necessarily because it's still a existing item //so it's children can probably be updated and we want that continue; } @@ -827,42 +839,42 @@ async function saveItems(vm) { //fields to update if post if (isPost) { vm.obj.items[i].id = res.data.id; - vm.obj.items[i].workorderId = res.data.workorderId; + vm.obj.items[i].quoteId = res.data.quoteId; - //walk all unsaved children and set the workorder item id so they can save + //walk all unsaved children and set the quote item id so they can save vm.obj.items[i].units.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].scheduledUsers.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].tasks.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].parts.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].labors.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].travels.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].expenses.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].loans.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); vm.obj.items[i].outsideServices.forEach( - z => (z.workorderItemId = vm.obj.items[i].id) + z => (z.quoteItemId = vm.obj.items[i].id) ); } } @@ -957,7 +969,7 @@ async function saveUnits(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].units[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits res.data.warrantyViz = null; //Add local key so it's reactive in vue vm.obj.items[woItemIndex].units.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update @@ -1000,7 +1012,7 @@ async function saveScheduledUsers(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].scheduledUsers[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].scheduledUsers.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1068,7 +1080,7 @@ async function saveTasks(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].tasks[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].tasks.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1174,7 +1186,7 @@ async function saveParts(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].parts[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].parts.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1210,7 +1222,7 @@ async function saveLabors(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].labors[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].labors.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1277,7 +1289,7 @@ async function saveTravels(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].travels[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].travels.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1373,7 +1385,7 @@ async function saveExpenses(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].scheduledUsers[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].expenses.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1437,7 +1449,7 @@ async function saveLoans(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].loans[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].loans.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1508,7 +1520,7 @@ async function saveOutsideServices(vm, woItemIndex) { childUid: vm.obj.items[woItemIndex].outsideServices[i].uid }); } else { - //Server will update fields on put or post for most workorder graph objecs so need to update entire object here + //Server will update fields on put or post for most quote graph objecs so need to update entire object here res.data.isDirty = false; //prime isDirty to detect future edits vm.obj.items[woItemIndex].outsideServices.splice(i, 1, res.data); //vue needs the splice rather than just setting the value in order to trigger reactivity or else the UI won't update } @@ -1635,10 +1647,13 @@ async function clickHandler(menuItem) { break; case "new": m.vm.$router.push({ - name: "workorder-edit", + name: "quote-edit", params: { recordid: 0 } }); break; + case "genwo": + m.vm.generateWorkOrder(); + break; case "duplicate": m.vm.duplicate(); break; @@ -1788,6 +1803,19 @@ function generateMenu(vm) { }); } + if ( + vm.rights.change && + vm.$route.params.recordid != 0 && + !vm.obj.userIsRestrictedType + ) { + menuOptions.menuItems.push({ + title: "QuoteGenerateServiceWorkOrder", + icon: "$ayiTools", + key: FORM_KEY + ":genwo", + vm: vm + }); + } + if ( vm.rights.change && vm.$route.params.recordid != 0 && @@ -1860,11 +1888,9 @@ async function fetchTranslatedText(vm) { "Customer", "QuoteSerialNumber", "WorkOrderSummary", - //"WorkOrderCloseByDate", + "QuoteGenerateServiceWorkOrder", "Contract", "Project", - //"WorkOrderInvoiceNumber", - //"WorkOrderServiceDate", "WorkOrderCustomerContactName", "WorkOrderCustomerReferenceNumber", "WorkOrderInternalReferenceNumber", diff --git a/ayanova/src/views/svc-workorder.vue b/ayanova/src/views/svc-workorder.vue index c9b4fe7d..1b8a418b 100644 --- a/ayanova/src/views/svc-workorder.vue +++ b/ayanova/src/views/svc-workorder.vue @@ -97,8 +97,20 @@ export default { } else { //new path if (this.$route.params.obj) { - //DUPLICATE + //DUPLICATE OR GEN FROM QUOTE OR PM this.obj = this.$route.params.obj; + + if (this.$route.params.fromQuote) { + //FROM QUOTE + //TODO: + //delete quote specific fields, set fromQuoteId, add a default state for new wo from global settings, add partrequests empty collection and any missing servicewo stuff + //handle copy wiki and copy attachments (somehow for attachments, maybe set a flag on first save if success it then triggers an attachment route that copies attachments to another object so not duped in system) + } else if (this.$route.params.fromPM) { + //FROM PM + //TODO: + //delete pm specific fields, set fromPMId, add a default state for new wo from global settings, add partrequests empty collection + } + this.obj.concurrency = undefined; this.obj.id = 0; this.obj.serial = 0;