diff --git a/ayanova/src/components/work-order-item-labors.vue b/ayanova/src/components/work-order-item-labors.vue new file mode 100644 index 00000000..0df5f725 --- /dev/null +++ b/ayanova/src/components/work-order-item-labors.vue @@ -0,0 +1,742 @@ + + + + + + + + $ayiMoneyBillWave + {{ $ay.t("WorkOrderItemLaborList") }} + + $ayiEllipsisV + + + + + + + $ayiPlus + + {{ $ay.t("New") }} + + + + $ayiTrashAlt + + {{ $ay.t("SoftDelete") }} + + + + $ayiTrashRestoreAlt + + {{ $ay.t("Undelete") }} + + + + + + + + + + + + + + {{ $ay.t("Undelete") + }}$ayiTrashRestoreAlt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ayanova/src/views/svc-workorder.vue b/ayanova/src/views/svc-workorder.vue index 0df30ffe..92453df3 100644 --- a/ayanova/src/views/svc-workorder.vue +++ b/ayanova/src/views/svc-workorder.vue @@ -737,6 +737,10 @@ async function saveItems(vm) { z => (z.workorderItemId = vm.obj.items[i].id) ); + vm.obj.items[i].labors.forEach( + z => (z.workorderItemId = vm.obj.items[i].id) + ); + //todo: other grandchildren } } @@ -751,6 +755,9 @@ async function saveItems(vm) { if (!vm.saveResult.fatal) { await saveScheduledUsers(vm, i); } + if (!vm.saveResult.fatal) { + await saveLabors(vm, i); + } //todo: other grandchildren //------ } @@ -865,9 +872,6 @@ async function saveScheduledUsers(vm, woItemIndex) { return; //made it } -///////////////////////////// -// SCHEDULED USERS -// async function deleteScheduledUsers(vm, woItemIndex) { //walk the array backwards as items may be spliced out for ( @@ -898,6 +902,71 @@ async function deleteScheduledUsers(vm, woItemIndex) { return; } +///////////////////////////// +// SCHEDULED USERS +// +async function saveLabors(vm, woItemIndex) { + //DELETE FLAGGED ITEMS FIRST + await deleteLabors(vm, woItemIndex); + if (vm.saveResult.fatal) { + return; + } + + for (let i = 0; i < vm.obj.items[woItemIndex].labors.length; i++) { + let o = vm.obj.items[woItemIndex].labors[i]; + if (o.isDirty) { + const isPost = o.id == 0; + let res = await window.$gz.api.upsert(`${API_BASE_URL}items/labors`, o); + if (res.error) { + handleSaveError(vm, { + error: res.error, + itemUid: vm.obj.items[woItemIndex].uid, + childKey: "labors", + childUid: o.uid + }); + } else { + //update any server changed fields + //always updated: + o.concurrency = res.data.concurrency; + o.isDirty = false; + + //new records only... + if (isPost) { + o.id = res.data.id; + o.workOrderItemId = res.data.workOrderItemId; + } + } + } + } + return; //made it +} + +async function deleteLabors(vm, woItemIndex) { + //walk the array backwards as items may be spliced out + for (var i = vm.obj.items[woItemIndex].labors.length - 1; i >= 0; i--) { + const d = vm.obj.items[woItemIndex].labors[i]; + if (!d.deleted) { + continue; + } + let res = await window.$gz.api.remove( + `${API_BASE_URL}items/labors/${d.id}` + ); + if (res.error) { + handleSaveError(vm, { + error: res.error, + itemUid: vm.obj.items[woItemIndex].uid, + childKey: "labors", + childUid: d.uid + }); + } else { + vm.obj.items[woItemIndex].labors.splice(i, 1); + } + } + + //---- + return; +} + //todo: other grandchildren //######################################### UTILITY METHODS ########################################### @@ -1273,7 +1342,20 @@ async function fetchTranslatedText(vm) { "WorkOrderItemExpenseReimburseUser", "WorkOrderItemExpenseTaxPaid", "WorkOrderItemExpenseTotalCost", - "WorkOrderItemExpenseUserID" + "WorkOrderItemExpenseUserID", + "WorkOrderItemLaborList", + "WorkOrderItemLaborServiceStartDate", + "WorkOrderItemLaborServiceStopDate", + "WorkOrderItemLaborServiceRateQuantity", + "WorkOrderItemLaborServiceRateID", + "WorkOrderItemLaborServiceDetails", + "WorkOrderItemLaborUserID", + "WorkOrderItemLaborNoChargeQuantity", + "WorkOrderItemLaborTaxRateSaleID", + "WorkOrderItemLaborManualDiscountPct", + "WorkOrderItemLaborBasePrice", + "WorkOrderItemLaborPrice", + "WorkOrderItemLaborServiceStartDate" ]); }