This commit is contained in:
@@ -37,28 +37,7 @@
|
|||||||
@input="fieldValueChanged('customerId')"
|
@input="fieldValueChanged('customerId')"
|
||||||
></gz-pick-list>
|
></gz-pick-list>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col
|
|
||||||
v-if="
|
|
||||||
form().showMe(this, 'CustomerSignature') &&
|
|
||||||
!(
|
|
||||||
value.userIsSubContractorFull ||
|
|
||||||
value.userIsSubContractorRestricted
|
|
||||||
)
|
|
||||||
"
|
|
||||||
cols="12"
|
|
||||||
sm="6"
|
|
||||||
lg="4"
|
|
||||||
xl="3"
|
|
||||||
>
|
|
||||||
<GzWoSignature
|
|
||||||
v-model="value"
|
|
||||||
:form-key="formCustomTemplateKey"
|
|
||||||
:readonly="formState.readOnly || value.userIsTechRestricted"
|
|
||||||
:pvm="pvm"
|
|
||||||
variant="customer"
|
|
||||||
data-cy="customerSignature"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
<v-col
|
<v-col
|
||||||
v-if="
|
v-if="
|
||||||
form().showMe(this, 'WorkOrderStatus') &&
|
form().showMe(this, 'WorkOrderStatus') &&
|
||||||
@@ -72,14 +51,14 @@
|
|||||||
lg="4"
|
lg="4"
|
||||||
xl="3"
|
xl="3"
|
||||||
>
|
>
|
||||||
<GzWoState
|
<GzQuoteState
|
||||||
v-model="value"
|
v-model="value"
|
||||||
:form-key="formCustomTemplateKey"
|
:form-key="formCustomTemplateKey"
|
||||||
:readonly="formState.readOnly"
|
:readonly="formState.readOnly"
|
||||||
:pvm="pvm"
|
:pvm="pvm"
|
||||||
data-cy="woState"
|
data-cy="woState"
|
||||||
:all-states="pvm.selectLists.wostatus"
|
:all-states="pvm.selectLists.quotestatus"
|
||||||
:allowed-states="pvm.selectLists.allowedwostatus"
|
:allowed-states="pvm.selectLists.allowedquotestatus"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
@@ -101,29 +80,6 @@
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col
|
|
||||||
v-if="
|
|
||||||
form().showMe(this, 'TechSignature') &&
|
|
||||||
!(
|
|
||||||
value.userIsSubContractorFull ||
|
|
||||||
value.userIsSubContractorRestricted
|
|
||||||
)
|
|
||||||
"
|
|
||||||
cols="12"
|
|
||||||
sm="6"
|
|
||||||
lg="4"
|
|
||||||
xl="3"
|
|
||||||
>
|
|
||||||
<GzWoSignature
|
|
||||||
v-model="value"
|
|
||||||
:form-key="formCustomTemplateKey"
|
|
||||||
:readonly="formState.readOnly || value.userIsTechRestricted"
|
|
||||||
:pvm="pvm"
|
|
||||||
variant="tech"
|
|
||||||
data-cy="techSignature"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<v-col
|
<v-col
|
||||||
v-if="
|
v-if="
|
||||||
form().showMe(this, 'WorkOrderSummary') &&
|
form().showMe(this, 'WorkOrderSummary') &&
|
||||||
@@ -450,14 +406,12 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/* XXXeslint-disable */
|
/* XXXeslint-disable */
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
import GzWoState from "./work-order-state.vue";
|
import GzQuoteState from "./quote-state.vue";
|
||||||
import GzWoAddress from "./work-order-address.vue";
|
import GzWoAddress from "./work-order-address.vue";
|
||||||
import GzWoSignature from "./work-order-signature.vue";
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GzWoState,
|
GzQuoteState,
|
||||||
GzWoAddress,
|
GzWoAddress
|
||||||
GzWoSignature
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -543,7 +497,7 @@ Example workorder
|
|||||||
wiki: null,
|
wiki: null,
|
||||||
customFields: null,
|
customFields: null,
|
||||||
tags: [],
|
tags: [],
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
techNotes: "technotes",
|
techNotes: "technotes",
|
||||||
workorderItemStatusId: null,
|
workorderItemStatusId: null,
|
||||||
workorderItemPriorityId: null,
|
workorderItemPriorityId: null,
|
||||||
@@ -565,7 +519,7 @@ Example workorder
|
|||||||
stopDate: null,
|
stopDate: null,
|
||||||
serviceRateId: null,
|
serviceRateId: null,
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
workOrderItemId: 21
|
quoteItemId: 21
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 42,
|
id: 42,
|
||||||
@@ -576,7 +530,7 @@ Example workorder
|
|||||||
stopDate: null,
|
stopDate: null,
|
||||||
serviceRateId: null,
|
serviceRateId: null,
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
workOrderItemId: 21
|
quoteItemId: 21
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tasks: [],
|
tasks: [],
|
||||||
@@ -591,7 +545,7 @@ Example workorder
|
|||||||
wiki: null,
|
wiki: null,
|
||||||
customFields: null,
|
customFields: null,
|
||||||
tags: [],
|
tags: [],
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
techNotes: "technotes",
|
techNotes: "technotes",
|
||||||
workorderItemStatusId: null,
|
workorderItemStatusId: null,
|
||||||
workorderItemPriorityId: null,
|
workorderItemPriorityId: null,
|
||||||
@@ -613,7 +567,7 @@ Example workorder
|
|||||||
stopDate: null,
|
stopDate: null,
|
||||||
serviceRateId: null,
|
serviceRateId: null,
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
workOrderItemId: 22
|
quoteItemId: 22
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 44,
|
id: 44,
|
||||||
@@ -624,7 +578,7 @@ Example workorder
|
|||||||
stopDate: null,
|
stopDate: null,
|
||||||
serviceRateId: null,
|
serviceRateId: null,
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
workOrderItemId: 22
|
quoteItemId: 22
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tasks: [],
|
tasks: [],
|
||||||
@@ -637,7 +591,7 @@ Example workorder
|
|||||||
{
|
{
|
||||||
id: 37,
|
id: 37,
|
||||||
concurrency: 7728489,
|
concurrency: 7728489,
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
workOrderStatusId: 2,
|
workOrderStatusId: 2,
|
||||||
created: "2021-05-29T21:30:31.421011Z",
|
created: "2021-05-29T21:30:31.421011Z",
|
||||||
userId: 37,
|
userId: 37,
|
||||||
@@ -647,7 +601,7 @@ Example workorder
|
|||||||
{
|
{
|
||||||
id: 38,
|
id: 38,
|
||||||
concurrency: 7728489,
|
concurrency: 7728489,
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
workOrderStatusId: 3,
|
workOrderStatusId: 3,
|
||||||
created: "2021-05-29T22:25:31.421011Z",
|
created: "2021-05-29T22:25:31.421011Z",
|
||||||
userId: 10,
|
userId: 10,
|
||||||
@@ -657,7 +611,7 @@ Example workorder
|
|||||||
{
|
{
|
||||||
id: 39,
|
id: 39,
|
||||||
concurrency: 7728489,
|
concurrency: 7728489,
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
workOrderStatusId: 1,
|
workOrderStatusId: 1,
|
||||||
created: "2021-05-29T22:30:31.421011Z",
|
created: "2021-05-29T22:30:31.421011Z",
|
||||||
userId: 31,
|
userId: 31,
|
||||||
@@ -667,7 +621,7 @@ Example workorder
|
|||||||
{
|
{
|
||||||
id: 40,
|
id: 40,
|
||||||
concurrency: 7728489,
|
concurrency: 7728489,
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
workOrderStatusId: 3,
|
workOrderStatusId: 3,
|
||||||
created: "2021-05-29T23:25:31.421011Z",
|
created: "2021-05-29T23:25:31.421011Z",
|
||||||
userId: 2,
|
userId: 2,
|
||||||
@@ -677,7 +631,7 @@ Example workorder
|
|||||||
{
|
{
|
||||||
id: 41,
|
id: 41,
|
||||||
concurrency: 7728489,
|
concurrency: 7728489,
|
||||||
workOrderId: 10,
|
quoteId: 10,
|
||||||
workOrderStatusId: 9,
|
workOrderStatusId: 9,
|
||||||
created: "2021-04-06T00:10:44.636Z",
|
created: "2021-04-06T00:10:44.636Z",
|
||||||
userId: 1,
|
userId: 1,
|
||||||
|
|||||||
798
ayanova/src/components/quote-item-expenses.vue
Normal file
798
ayanova/src/components/quote-item-expenses.vue
Normal file
@@ -0,0 +1,798 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiMoneyBillWave</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemExpenseList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="expensesTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
<template v-slot:[`item.reimburseUser`]="{ item }">
|
||||||
|
<v-simple-checkbox
|
||||||
|
v-model="item.reimburseUser"
|
||||||
|
disabled
|
||||||
|
></v-simple-checkbox>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:[`item.chargeToCustomer`]="{ item }">
|
||||||
|
<v-simple-checkbox
|
||||||
|
v-model="item.chargeToCustomer"
|
||||||
|
disabled
|
||||||
|
></v-simple-checkbox>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="expensetopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemExpenseName')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex].name
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseName')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
|
||||||
|
"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].name`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemExpenseTotalCost')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex].totalCost
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseTotalCost')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
|
||||||
|
"
|
||||||
|
data-cy="expenseTotalCost"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].totalCost`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemExpenseChargeAmount') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex]
|
||||||
|
.chargeAmount
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseChargeAmount')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
|
||||||
|
"
|
||||||
|
data-cy="expenseChargeAmount"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeAmount`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemExpenseChargeToCustomer') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-checkbox
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex]
|
||||||
|
.chargeToCustomer
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseChargeToCustomer')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
|
||||||
|
"
|
||||||
|
data-cy="chargeToCustomer"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@change="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeToCustomer`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></v-checkbox>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemExpenseTaxPaid')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex].taxPaid
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseTaxPaid')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
|
||||||
|
"
|
||||||
|
data-cy="expenseTaxPaid"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].taxPaid`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemExpenseChargeTaxCodeID') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TaxCode"
|
||||||
|
show-edit-icon
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex]
|
||||||
|
.chargeTaxCodeId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseChargeTaxCodeID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
|
||||||
|
"
|
||||||
|
data-cy="expenseChargeTaxCode"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].chargeTaxCodeId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="taxCodeChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemExpenseReimburseUser') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-checkbox
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex]
|
||||||
|
.reimburseUser
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseReimburseUser')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
|
||||||
|
"
|
||||||
|
data-cy="expenseReimburseUser"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@change="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].reimburseUser`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></v-checkbox>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemExpenseUserID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().User"
|
||||||
|
variant="tech"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex].userId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseUserID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
|
||||||
|
"
|
||||||
|
data-cy="expenseUser"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="userChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemExpenseDescription')"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<v-textarea
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].expenses[activeItemIndex]
|
||||||
|
.description
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemExpenseDescription')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
|
||||||
|
"
|
||||||
|
data-cy="expenseDescription"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].expenses[${activeItemIndex}].description`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.expensetopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
userChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
].userViz = newName;
|
||||||
|
},
|
||||||
|
taxCodeChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
].taxCodeViz = newName;
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].expenses.length;
|
||||||
|
|
||||||
|
//#################################### IMPORTANT ##################################################
|
||||||
|
//NOTE: default values are critical and must match server validation ExpenseValidateAsync for restricted users
|
||||||
|
//so that they are in agreement otherwise restricted users will never be able to create new records
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
description: null,
|
||||||
|
name: null,
|
||||||
|
totalCost: 0,
|
||||||
|
chargeAmount: 0,
|
||||||
|
taxPaid: 0,
|
||||||
|
chargeTaxCodeId: null,
|
||||||
|
taxCodeViz: null,
|
||||||
|
reimburseUser: false,
|
||||||
|
userId: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userId
|
||||||
|
: null,
|
||||||
|
userViz: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userName
|
||||||
|
: null,
|
||||||
|
chargeToCustomer: false,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now() //used for error tracking / display
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (
|
||||||
|
this.hasData &&
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses.length == 1
|
||||||
|
) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
|
||||||
|
// //set viz if applicable
|
||||||
|
// if(ref==""){
|
||||||
|
// let selectedPartWarehouse = vm.$refs.partWarehouseId.getFullSelectionValue();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[item.index]
|
||||||
|
.deleted === true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Expenses[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[
|
||||||
|
this.activeItemIndex
|
||||||
|
] == null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].expenses[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseName")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseName"),
|
||||||
|
align: "start",
|
||||||
|
value: "name"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseTotalCost")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseTotalCost"),
|
||||||
|
align: "right",
|
||||||
|
value: "totalCost"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseChargeAmount")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseChargeAmount"),
|
||||||
|
align: "right",
|
||||||
|
value: "chargeAmount"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseChargeToCustomer")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseChargeToCustomer"),
|
||||||
|
align: "center",
|
||||||
|
value: "chargeToCustomer"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseTaxPaid")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseTaxPaid"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxPaid"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseChargeTaxCodeID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Tax"),
|
||||||
|
align: "left",
|
||||||
|
value: "taxCodeViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "ExpenseTaxAViz")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxAAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxAViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "ExpenseTaxBViz")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxBAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxBViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "ExpenseLineTotalViz")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("LineTotal"),
|
||||||
|
align: "right",
|
||||||
|
value: "lineTotalViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseReimburseUser")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseReimburseUser"),
|
||||||
|
align: "center",
|
||||||
|
value: "reimburseUser"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemExpenseUserID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemExpenseUserID"),
|
||||||
|
align: "left",
|
||||||
|
value: "userViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].expenses.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
name: x.name,
|
||||||
|
totalCost: window.$gz.locale.currencyLocalized(
|
||||||
|
x.totalCost,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
chargeAmount: window.$gz.locale.currencyLocalized(
|
||||||
|
x.chargeAmount,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
chargeToCustomer: x.chargeToCustomer,
|
||||||
|
taxPaid: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxPaid,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxCodeViz: x.taxCodeViz,
|
||||||
|
taxAViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxAViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxBViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxBViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
lineTotalViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.lineTotalViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
reimburseUser: x.reimburseUser,
|
||||||
|
userViz: x.userViz
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].expenses.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return this.activeItemIndex != null && this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
997
ayanova/src/components/quote-item-labors.vue
Normal file
997
ayanova/src/components/quote-item-labors.vue
Normal file
@@ -0,0 +1,997 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiHammer</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemLaborList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
v-if="hasSelection && !formState.readOnly"
|
||||||
|
@click="appendTasks"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTasks</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("AppendTasks") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="laborsTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="labortopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborServiceStartDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemLaborServiceStartDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.serviceStartDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
|
||||||
|
"
|
||||||
|
data-cy="serviceStartDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborServiceStopDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemLaborServiceStopDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.serviceStopDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
|
||||||
|
"
|
||||||
|
data-cy="serviceStopDate"
|
||||||
|
:rules="[
|
||||||
|
form().datePrecedence(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStartDate`,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceStopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborServiceRateQuantity')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.serviceRateQuantity
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborServiceRateQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
|
||||||
|
"
|
||||||
|
data-cy="laborServiceRateQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborServiceRateID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().ServiceRate"
|
||||||
|
:variant="'contractid:' + value.contractId"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.serviceRateId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborServiceRateID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
|
||||||
|
"
|
||||||
|
data-cy="labors.serviceRateId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="rateChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborUserID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().User"
|
||||||
|
variant="tech"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex].userId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborUserID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
|
||||||
|
"
|
||||||
|
data-cy="labors.userid"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="userChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborNoChargeQuantity')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.noChargeQuantity
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborNoChargeQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
|
||||||
|
"
|
||||||
|
data-cy="laborNoChargeQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].noChargeQuantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(`Items[${activeWoItemIndex}].labors[
|
||||||
|
${activeItemIndex}
|
||||||
|
].noChargeQuantity`)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemLaborTaxRateSaleID') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TaxCode"
|
||||||
|
show-edit-icon
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.taxCodeSaleId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborTaxRateSaleID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
"
|
||||||
|
data-cy="laborTaxCodeSaleId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="taxCodeChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'LaborPriceOverride') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.priceOverride
|
||||||
|
"
|
||||||
|
can-clear
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('PriceOverride')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
|
||||||
|
"
|
||||||
|
data-cy="laborpriceoverride"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLaborServiceDetails')"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<v-textarea
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].labors[activeItemIndex]
|
||||||
|
.serviceDetails
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLaborServiceDetails')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
|
||||||
|
"
|
||||||
|
data-cy="laborserviceDetails"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].labors[${activeItemIndex}].serviceDetails`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.labortopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
appendTasks() {
|
||||||
|
const tasks = this.value.items[this.activeWoItemIndex].tasks;
|
||||||
|
if (tasks.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const l = this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
];
|
||||||
|
let at = "";
|
||||||
|
tasks.forEach(z => {
|
||||||
|
at += `${z.task} - ${z.statusViz}\n`;
|
||||||
|
});
|
||||||
|
l.serviceDetails += `\n${at}`;
|
||||||
|
},
|
||||||
|
userChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].userViz = newName;
|
||||||
|
},
|
||||||
|
rateChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateViz = newName;
|
||||||
|
},
|
||||||
|
taxCodeChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].taxCodeViz = newName;
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].labors.length;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].labors.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
userId: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userId
|
||||||
|
: null,
|
||||||
|
serviceStartDate: null,
|
||||||
|
serviceStopDate: null,
|
||||||
|
serviceRateId: null,
|
||||||
|
serviceDetails: null,
|
||||||
|
serviceRateQuantity: 0,
|
||||||
|
noChargeQuantity: 0,
|
||||||
|
taxCodeSaleId: null,
|
||||||
|
price: 0,
|
||||||
|
priceOverride: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
userViz: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userName
|
||||||
|
: null,
|
||||||
|
serviceRateViz: null,
|
||||||
|
taxCodeViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].labors.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
//------- SPECIAL HANDLING OF CHANGES -----------
|
||||||
|
const isNew =
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
|
||||||
|
.id == 0;
|
||||||
|
|
||||||
|
//Auto calculate dates / quantities / global defaults
|
||||||
|
const dStart = this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceStartDate;
|
||||||
|
const dStop = this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceStopDate;
|
||||||
|
if (ref.includes("serviceStartDate") && dStart != null) {
|
||||||
|
this.handleStartDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
if (ref.includes("serviceStopDate") && dStop != null) {
|
||||||
|
this.handleStopDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStartDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStop == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set stop date based on start date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceStopDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStart,
|
||||||
|
globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStop != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStopDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStart == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set start date based on stop date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceStartDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStop,
|
||||||
|
0 - globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStart != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[item.index].deleted ===
|
||||||
|
true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Labors[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex] ==
|
||||||
|
null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].labors[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborServiceStartDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborServiceStartDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "serviceStartDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborServiceStopDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborServiceStopDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "serviceStopDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborServiceRateQuantity")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborServiceRateQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "serviceRateQuantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborServiceRateID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborServiceRateID"),
|
||||||
|
align: "left",
|
||||||
|
value: "serviceRateViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborServiceDetails")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborServiceDetails"),
|
||||||
|
align: "left",
|
||||||
|
value: "serviceDetails"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborUserID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborUserID"),
|
||||||
|
align: "left",
|
||||||
|
value: "userViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLaborNoChargeQuantity")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLaborNoChargeQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "noChargeQuantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "LaborUnitOfMeasureViz")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitOfMeasure"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitOfMeasureViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborCostViz") &&
|
||||||
|
this.value.userCanViewLaborOrTravelRateCosts &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Cost"),
|
||||||
|
align: "right",
|
||||||
|
value: "costViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborListPriceViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("ListPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "listPriceViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborPriceOverride") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("PriceOverride"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceOverride"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborPriceViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Price"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemLaborTaxRateSaleID") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Tax"),
|
||||||
|
align: "left",
|
||||||
|
value: "taxCodeViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborNetViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("NetPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "netViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborTaxAViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxAAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxAViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborTaxBViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxBAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxBViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LaborLineTotalViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("LineTotal"),
|
||||||
|
align: "right",
|
||||||
|
value: "lineTotalViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].labors.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
serviceStartDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.serviceStartDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
serviceStopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.serviceStopDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
|
||||||
|
serviceRateQuantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.serviceRateQuantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
serviceRateViz: x.serviceRateViz,
|
||||||
|
userViz: x.userViz,
|
||||||
|
noChargeQuantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.noChargeQuantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
unitOfMeasureViz: x.unitOfMeasureViz,
|
||||||
|
costViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.costViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
listPriceViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.listPriceViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
priceViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxCodeViz: x.taxCodeViz,
|
||||||
|
priceOverride: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceOverride,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
netViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.netViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxAViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxAViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxBViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxBViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
lineTotalViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.lineTotalViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
serviceDetails: window.$gz.util.truncateString(
|
||||||
|
x.serviceDetails,
|
||||||
|
this.pvm.maxTableNotesLength
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].labors.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return this.activeItemIndex != null && this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
//----
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
885
ayanova/src/components/quote-item-loans.vue
Normal file
885
ayanova/src/components/quote-item-loans.vue
Normal file
@@ -0,0 +1,885 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiPlug</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemLoanList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("New")
|
||||||
|
}}</v-list-item-title> </v-list-item
|
||||||
|
><v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="loansTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="loantopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLoanUnit')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().LoanUnit"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].loanUnitId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLoanUnit')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
|
||||||
|
"
|
||||||
|
data-cy="loans.loanUnitId"
|
||||||
|
:rules="[
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].loanUnitId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="loanUnitChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemLoanRate') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-select
|
||||||
|
v-model="value.items[activeWoItemIndex].loans[activeItemIndex].rate"
|
||||||
|
:items="pvm.selectLists.loanUnitRateUnits"
|
||||||
|
item-text="name"
|
||||||
|
item-value="id"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLoanRate')"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`"
|
||||||
|
data-cy="loanUnitRateUnit"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].rate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@change="loanUnitRateUnitChange"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemLoanQuantity') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].quantity
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLoanQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
|
||||||
|
"
|
||||||
|
data-cy="loanQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].quantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLoanOutDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemLoanOutDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].outDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
|
||||||
|
"
|
||||||
|
data-cy="loanUnitOutDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].outDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLoanDueDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemLoanDueDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].dueDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
|
||||||
|
"
|
||||||
|
data-cy="loanUnitDueDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].dueDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemLoanReturnDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemLoanReturnDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].returnDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
|
||||||
|
"
|
||||||
|
data-cy="loanUnitReturnDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].returnDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemLoanTaxCodeID') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TaxCode"
|
||||||
|
show-edit-icon
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].taxCodeId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLoanTaxCodeID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
|
||||||
|
"
|
||||||
|
data-cy="loanTaxCodeSaleId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].taxCodeId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="taxCodeChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'LoanPriceOverride') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex]
|
||||||
|
.priceOverride
|
||||||
|
"
|
||||||
|
can-clear
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('PriceOverride')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
|
||||||
|
"
|
||||||
|
data-cy="loanpriceoverride"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col v-if="form().showMe(this, 'WorkOrderItemLoanNotes')" cols="12">
|
||||||
|
<v-textarea
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].loans[activeItemIndex].notes
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemLoanNotes')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`"
|
||||||
|
data-cy="loanUnitNotes"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].loans[${activeItemIndex}].notes`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.loantopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loanUnitRateUnitChange(newId) {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].unitOfMeasureViz = this.pvm.selectLists.loanUnitRateUnits.find(
|
||||||
|
s => s.id == newId
|
||||||
|
).name;
|
||||||
|
},
|
||||||
|
loanUnitChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].loanUnitViz = newName;
|
||||||
|
},
|
||||||
|
taxCodeChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].taxCodeViz = newName;
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].loans.length;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].loans.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
notes: null,
|
||||||
|
outDate: null,
|
||||||
|
dueDate: null,
|
||||||
|
returnDate: null,
|
||||||
|
taxCodeId: null,
|
||||||
|
loanUnitId: 0, //zero to break rule on new
|
||||||
|
quantity: 1,
|
||||||
|
rate: 1,
|
||||||
|
cost: 0,
|
||||||
|
priceOverride: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
loanUnitViz: null,
|
||||||
|
taxCodeViz: null,
|
||||||
|
unitOfMeasureViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
//trigger rule breaking / validation
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].loanUnitId = null;
|
||||||
|
this.fieldValueChanged(
|
||||||
|
`Items[${this.activeWoItemIndex}].loans[${this.activeItemIndex}].loanUnitId`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].loans.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].loans.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[item.index].deleted ===
|
||||||
|
true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Loans[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[this.activeItemIndex] ==
|
||||||
|
null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].loans[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLoanUnit")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanUnit"),
|
||||||
|
align: "left",
|
||||||
|
value: "loanUnitViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemLoanRate") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanRate"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitOfMeasureViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemLoanQuantity") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "quantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLoanOutDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanOutDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "outDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLoanDueDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanDueDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "dueDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLoanReturnDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanReturnDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "returnDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemLoanNotes")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemLoanNotes"),
|
||||||
|
align: "left",
|
||||||
|
value: "notes"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanCost") &&
|
||||||
|
this.value.userCanViewLoanerCosts &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Cost"),
|
||||||
|
align: "right",
|
||||||
|
value: "cost"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanListPrice") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("ListPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "listPrice"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanPriceOverride") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("PriceOverride"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceOverride"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanPriceViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Price"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemLoanTaxCodeID") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Tax"),
|
||||||
|
align: "left",
|
||||||
|
value: "taxCodeViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanNetViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("NetPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "netViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanTaxAViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxAAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxAViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanTaxBViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxBAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxBViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "LoanLineTotalViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("LineTotal"),
|
||||||
|
align: "right",
|
||||||
|
value: "lineTotalViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].loans.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
loanUnitViz: x.loanUnitViz,
|
||||||
|
unitOfMeasureViz: x.unitOfMeasureViz,
|
||||||
|
quantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.quantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
outDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.outDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
dueDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.dueDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
returnDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.returnDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
notes: window.$gz.util.truncateString(
|
||||||
|
x.notes,
|
||||||
|
this.pvm.maxTableNotesLength
|
||||||
|
),
|
||||||
|
|
||||||
|
cost: window.$gz.locale.currencyLocalized(
|
||||||
|
x.cost,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
listPrice: window.$gz.locale.currencyLocalized(
|
||||||
|
x.listPrice,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
priceViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxCodeViz: x.taxCodeViz,
|
||||||
|
priceOverride: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceOverride,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
netViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.netViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxAViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxAViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxBViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxBViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
lineTotalViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.lineTotalViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].loans.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return (
|
||||||
|
this.activeItemIndex != null &&
|
||||||
|
this.canDeleteAll &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
);
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
1098
ayanova/src/components/quote-item-outside-services.vue
Normal file
1098
ayanova/src/components/quote-item-outside-services.vue
Normal file
File diff suppressed because it is too large
Load Diff
1129
ayanova/src/components/quote-item-parts.vue
Normal file
1129
ayanova/src/components/quote-item-parts.vue
Normal file
File diff suppressed because it is too large
Load Diff
710
ayanova/src/components/quote-item-scheduled-users.vue
Normal file
710
ayanova/src/components/quote-item-scheduled-users.vue
Normal file
@@ -0,0 +1,710 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiUserClock</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemScheduledUserList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
v-if="hasSelection && !formState.readOnly"
|
||||||
|
@click="convertToLabor"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiHammer</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("WorkOrderConvertScheduledUserToLabor")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
v-if="!formState.readOnly && hasMultipleItems"
|
||||||
|
@click="convertAllToLabor"
|
||||||
|
>
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiHammer</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("WorkOrderConvertAllScheduledUsersToLabor")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ################################ SCHEDULED USERS TABLE ############################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="scheduledUsersTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="scheduledusertopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemScheduledUserStartDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemScheduledUserStartDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
|
||||||
|
.startDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
|
||||||
|
"
|
||||||
|
data-cy="startDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemScheduledUserStopDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemScheduledUserStopDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
|
||||||
|
.stopDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
|
||||||
|
"
|
||||||
|
data-cy="stopDate"
|
||||||
|
:rules="[
|
||||||
|
form().datePrecedence(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].startDate`,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].stopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemScheduledUserEstimatedQuantity')
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
|
||||||
|
.estimatedQuantity
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemScheduledUserEstimatedQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
|
||||||
|
"
|
||||||
|
data-cy="scheduledUsers.EstimatedQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].estimatedQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemScheduledUserUserID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().User"
|
||||||
|
variant="tech"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
|
||||||
|
.userId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemScheduledUserUserID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
|
||||||
|
"
|
||||||
|
data-cy="scheduledUsers.userid"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="userChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemScheduledUserServiceRateID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().ServiceRate"
|
||||||
|
:variant="'contractid:' + value.contractId"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].scheduledUsers[activeItemIndex]
|
||||||
|
.serviceRateId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemScheduledUserServiceRateID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
|
||||||
|
"
|
||||||
|
data-cy="scheduledUsers.serviceRateId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].scheduledUsers[${activeItemIndex}].serviceRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="rateChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.scheduledusertopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
convertAllToLabor() {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers.forEach(z => {
|
||||||
|
this.doConvertToLabor(z);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
convertToLabor() {
|
||||||
|
this.doConvertToLabor(
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
doConvertToLabor(s) {
|
||||||
|
this.value.items[this.activeWoItemIndex].labors.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
userId: s.userId,
|
||||||
|
serviceStartDate: s.startDate,
|
||||||
|
serviceStopDate: s.stopDate,
|
||||||
|
serviceRateId: s.serviceRateId,
|
||||||
|
serviceDetails: null,
|
||||||
|
serviceRateQuantity: s.estimatedQuantity,
|
||||||
|
noChargeQuantity: 0,
|
||||||
|
taxCodeSaleId: null,
|
||||||
|
price: 0,
|
||||||
|
priceOverride: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
userViz: s.userViz,
|
||||||
|
serviceRateViz: s.serviceRateViz,
|
||||||
|
taxCodeViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
userChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].userViz = newName;
|
||||||
|
},
|
||||||
|
rateChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].serviceRateViz = newName;
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].scheduledUsers
|
||||||
|
.length;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
userId: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userId
|
||||||
|
: null,
|
||||||
|
estimatedQuantity: 0,
|
||||||
|
startDate: null,
|
||||||
|
stopDate: null,
|
||||||
|
serviceRateId: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
userViz: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userName
|
||||||
|
: null,
|
||||||
|
serviceRateViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].scheduledUsers.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
//------- SPECIAL HANDLING OF CHANGES -----------
|
||||||
|
const isNew =
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].id == 0;
|
||||||
|
|
||||||
|
//Auto calculate dates / quantities / global defaults
|
||||||
|
const dStart = this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].startDate;
|
||||||
|
const dStop = this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].stopDate;
|
||||||
|
if (ref.includes("startDate") && dStart != null) {
|
||||||
|
this.handleStartDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
if (ref.includes("stopDate") && dStop != null) {
|
||||||
|
this.handleStopDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStartDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStop == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set stop date based on start date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].stopDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStart,
|
||||||
|
globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].estimatedQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStop != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].estimatedQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStopDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workLaborScheduleDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStart == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set start date based on stop date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].startDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStop,
|
||||||
|
0 - globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].estimatedQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStart != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].estimatedQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[item.index]
|
||||||
|
.deleted === true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].ScheduledUsers[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
] == null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].scheduledUsers[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemScheduledUserStartDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemScheduledUserStartDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "startDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemScheduledUserStopDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemScheduledUserStopDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "stopDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemScheduledUserEstimatedQuantity")
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemScheduledUserEstimatedQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "estimatedQuantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemScheduledUserUserID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemScheduledUserUserID"),
|
||||||
|
align: "left",
|
||||||
|
value: "userViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemScheduledUserServiceRateID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemScheduledUserServiceRateID"),
|
||||||
|
align: "left",
|
||||||
|
value: "serviceRateViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].scheduledUsers.map(
|
||||||
|
(x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
startDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.startDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
stopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.stopDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
estimatedQuantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.estimatedQuantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
userViz: x.userViz,
|
||||||
|
serviceRateViz: x.serviceRateViz
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return (
|
||||||
|
this.activeItemIndex != null &&
|
||||||
|
this.canDeleteAll &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
);
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
},
|
||||||
|
hasMultipleItems: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].scheduledUsers.length > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
644
ayanova/src/components/quote-item-tasks.vue
Normal file
644
ayanova/src/components/quote-item-tasks.vue
Normal file
@@ -0,0 +1,644 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiTasks</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemTasks") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canAdd" @click="taskGroupDialog = true">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTasks</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("TaskGroup") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="expensesTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="tasktopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTaskSequence')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].tasks[activeItemIndex].sequence
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('Sequence')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().integerValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].sequence`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
type="number"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(
|
||||||
|
this,
|
||||||
|
'WorkOrderItemTaskWorkOrderItemTaskCompletionType'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-select
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].tasks[activeItemIndex].status
|
||||||
|
"
|
||||||
|
:items="pvm.selectLists.woItemTaskCompletionTypes"
|
||||||
|
item-text="name"
|
||||||
|
item-value="id"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTaskWorkOrderItemTaskCompletionType')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
|
||||||
|
"
|
||||||
|
data-cy="usertype"
|
||||||
|
:rules="[
|
||||||
|
form().integerValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].status`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@change="statusChange"
|
||||||
|
></v-select>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTaskUser')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().User"
|
||||||
|
variant="tech"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].tasks[activeItemIndex]
|
||||||
|
.completedByUserId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTaskUser')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
|
||||||
|
"
|
||||||
|
data-cy="expenseUser"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedByUserId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="userChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTaskCompletedDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemTaskCompletedDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].tasks[activeItemIndex]
|
||||||
|
.completedDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
|
||||||
|
"
|
||||||
|
data-cy="travelCompletedDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].completedDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col v-if="form().showMe(this, 'WorkOrderItemTaskTaskID')" cols="12">
|
||||||
|
<v-textarea
|
||||||
|
v-model="value.items[activeWoItemIndex].tasks[activeItemIndex].task"
|
||||||
|
:readonly="formState.readOnly || value.userIsRestrictedType"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTaskTaskID')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`"
|
||||||
|
data-cy="task"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].tasks[${activeItemIndex}].task`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
<!-- ################################################################################-->
|
||||||
|
<!-- ########################## GROUP SELECTOR FORM ###############################-->
|
||||||
|
<!-- ################################################################################-->
|
||||||
|
<template>
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-dialog max-width="600px" v-model="taskGroupDialog">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title> </v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TaskGroup"
|
||||||
|
show-edit-icon
|
||||||
|
v-model="selectedTaskGroup"
|
||||||
|
:label="$ay.t('TaskGroupList')"
|
||||||
|
ref="selectedTaskGroup"
|
||||||
|
data-cy="selectedTaskGroup"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn text @click="taskGroupDialog = false" color="primary">{{
|
||||||
|
$ay.t("Cancel")
|
||||||
|
}}</v-btn>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
:disabled="selectedTaskGroup == null"
|
||||||
|
color="primary"
|
||||||
|
text
|
||||||
|
@click="addTaskGroup()"
|
||||||
|
class="ml-4"
|
||||||
|
>{{ $ay.t("Add") }}</v-btn
|
||||||
|
>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: [],
|
||||||
|
taskGroupDialog: false,
|
||||||
|
selectedTaskGroup: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.tasktopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async addTaskGroup() {
|
||||||
|
let res = await window.$gz.api.get(
|
||||||
|
`task-group/${this.selectedTaskGroup}`
|
||||||
|
);
|
||||||
|
if (res.data && res.data.items) {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].tasks.length;
|
||||||
|
let incompleteViz = this.pvm.selectLists.woItemTaskCompletionTypes.find(
|
||||||
|
s => s.id == 1 //incomplete
|
||||||
|
).name;
|
||||||
|
res.data.items.forEach(z => {
|
||||||
|
newIndex++;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
sequence: newIndex,
|
||||||
|
task: z.task,
|
||||||
|
status: 1, //incomplete==1
|
||||||
|
statusViz: incompleteViz,
|
||||||
|
completedByUserId: null,
|
||||||
|
completedDate: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
completedByUserViz: null
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.taskGroupDialog = false;
|
||||||
|
},
|
||||||
|
userChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].completedByUserViz = newName;
|
||||||
|
},
|
||||||
|
statusChange(newStatusId) {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].statusViz = this.pvm.selectLists.woItemTaskCompletionTypes.find(
|
||||||
|
s => s.id == newStatusId
|
||||||
|
).name;
|
||||||
|
|
||||||
|
//completed date auto set by status change if not a todo
|
||||||
|
if (newStatusId != 1) {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].completedDate = window.$gz.locale.nowUTC8601String();
|
||||||
|
} else {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].completedDate = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].tasks.length;
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
sequence: newIndex + 1, //indexes are zero based but sequences are visible to user so 1 based
|
||||||
|
task: undefined, //to trigger validation on new
|
||||||
|
status: 1, //incomplete==1
|
||||||
|
completedByUserId: null,
|
||||||
|
completedDate: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
completedByUserViz: null,
|
||||||
|
statusViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
//trigger rule breaking / validation
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].task = null;
|
||||||
|
this.fieldValueChanged(
|
||||||
|
`Items[${this.activeWoItemIndex}].tasks[${this.activeItemIndex}].task`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].tasks.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[item.index].deleted ===
|
||||||
|
true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Tasks[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex] ==
|
||||||
|
null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].tasks[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTaskSequence")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Sequence"),
|
||||||
|
align: "left",
|
||||||
|
value: "sequence"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTaskTaskID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTaskTaskID"),
|
||||||
|
align: "start",
|
||||||
|
value: "task"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTaskUser")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTaskUser"),
|
||||||
|
align: "start",
|
||||||
|
value: "completedByUserViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(
|
||||||
|
this,
|
||||||
|
"WorkOrderItemTaskWorkOrderItemTaskCompletionType"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTaskWorkOrderItemTaskCompletionType"),
|
||||||
|
align: "start",
|
||||||
|
value: "statusViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTaskCompletedDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTaskCompletedDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "completedDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].tasks
|
||||||
|
.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
sequence: x.sequence,
|
||||||
|
task: x.task,
|
||||||
|
completedByUserViz: x.completedByUserViz,
|
||||||
|
statusViz: x.statusViz,
|
||||||
|
completedDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.completedDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a, b) => a.sequence - b.sequence);
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].tasks.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return (
|
||||||
|
this.activeItemIndex != null &&
|
||||||
|
this.canDeleteAll &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
);
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
976
ayanova/src/components/quote-item-travels.vue
Normal file
976
ayanova/src/components/quote-item-travels.vue
Normal file
@@ -0,0 +1,976 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiTruckMonster</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemTravelList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="travelsTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="traveltopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelStartDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemTravelStartDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.travelStartDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
|
||||||
|
"
|
||||||
|
data-cy="travelStartDate"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelStopDate')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-date-time-picker
|
||||||
|
:label="$ay.t('WorkOrderItemTravelStopDate')"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.travelStopDate
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
|
||||||
|
"
|
||||||
|
data-cy="travelStopDate"
|
||||||
|
:rules="[
|
||||||
|
form().datePrecedence(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStartDate`,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelStopDate`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-date-time-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelRateQuantity')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.travelRateQuantity
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelRateQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
|
||||||
|
"
|
||||||
|
data-cy="travelTravelRateQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelServiceRateID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TravelRate"
|
||||||
|
:variant="'contractid:' + value.contractId"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.travelRateId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelServiceRateID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
|
||||||
|
"
|
||||||
|
data-cy="travels.travelRateId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelRateId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="rateChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelUserID')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().User"
|
||||||
|
variant="tech"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex].userId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelUserID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
|
||||||
|
"
|
||||||
|
data-cy="travels.userid"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].userId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="userChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelNoChargeQuantity')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-decimal
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.noChargeQuantity
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelNoChargeQuantity')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
|
||||||
|
"
|
||||||
|
data-cy="travelNoChargeQuantity"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
|
||||||
|
),
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].noChargeQuantity`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-decimal>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemTravelTaxRateSaleID') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().TaxCode"
|
||||||
|
show-edit-icon
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.taxCodeSaleId
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelTaxRateSaleID')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
"
|
||||||
|
data-cy="travelTaxCodeSaleId"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].taxCodeSaleId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="taxCodeChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'TravelPriceOverride') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-currency
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.priceOverride
|
||||||
|
"
|
||||||
|
can-clear
|
||||||
|
:readonly="formState.readOnly || isDeleted"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('PriceOverride')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
|
||||||
|
"
|
||||||
|
data-cy="travelpriceoverride"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:rules="[
|
||||||
|
form().decimalValid(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].priceOverride`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-currency>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemTravelDetails')"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<v-textarea
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].travels[activeItemIndex]
|
||||||
|
.travelDetails
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemTravelDetails')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
|
||||||
|
"
|
||||||
|
data-cy="traveltravelDetails"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].travels[${activeItemIndex}].travelDetails`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.traveltopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
userChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].userViz = newName;
|
||||||
|
},
|
||||||
|
rateChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelRateViz = newName;
|
||||||
|
},
|
||||||
|
taxCodeChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].taxCodeViz = newName;
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].travels.length;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].travels.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
userId: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userId
|
||||||
|
: null,
|
||||||
|
travelStartDate: null,
|
||||||
|
travelStopDate: null,
|
||||||
|
travelRateId: null,
|
||||||
|
travelDetails: null,
|
||||||
|
travelRateQuantity: 0,
|
||||||
|
noChargeQuantity: 0,
|
||||||
|
taxCodeSaleId: null,
|
||||||
|
price: 0,
|
||||||
|
priceOverride: null,
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
userViz: this.$store.getters.isScheduleableUser
|
||||||
|
? this.$store.state.userName
|
||||||
|
: null,
|
||||||
|
travelRateViz: null,
|
||||||
|
taxCodeViz: null
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].travels.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
//------- SPECIAL HANDLING OF CHANGES -----------
|
||||||
|
const isNew =
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
|
||||||
|
.id == 0;
|
||||||
|
|
||||||
|
//Auto calculate dates / quantities / global defaults
|
||||||
|
const dStart = this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelStartDate;
|
||||||
|
const dStop = this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelStopDate;
|
||||||
|
if (ref.includes("travelStartDate") && dStart != null) {
|
||||||
|
this.handleStartDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
if (ref.includes("travelStopDate") && dStop != null) {
|
||||||
|
this.handleStopDateChange(isNew, dStart, dStop);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStartDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStop == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set stop date based on start date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelStopDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStart,
|
||||||
|
globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelRateQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStop != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleStopDateChange: function(isNew, dStart, dStop) {
|
||||||
|
const globalMinutes =
|
||||||
|
window.$gz.store.state.globalSettings.workOrderTravelDefaultMinutes;
|
||||||
|
|
||||||
|
if (isNew && dStart == null) {
|
||||||
|
if (globalMinutes != 0) {
|
||||||
|
//set start date based on stop date and global minutes
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelStartDate = window.$gz.locale.addMinutesToUTC8601String(
|
||||||
|
dStop,
|
||||||
|
0 - globalMinutes
|
||||||
|
);
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelRateQuantity = globalMinutes;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Existing record or both dates filled, just update quantity
|
||||||
|
if (dStart != null) {
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
].travelRateQuantity = window.$gz.locale.diffHoursFromUTC8601String(
|
||||||
|
dStart,
|
||||||
|
dStop
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[item.index].deleted ===
|
||||||
|
true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Travels[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[
|
||||||
|
this.activeItemIndex
|
||||||
|
] == null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].travels[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelStartDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelStartDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "travelStartDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelStopDate")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelStopDate"),
|
||||||
|
align: "right",
|
||||||
|
value: "travelStopDate"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelRateQuantity")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelRateQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "travelRateQuantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelServiceRateID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelServiceRateID"),
|
||||||
|
align: "left",
|
||||||
|
value: "travelRateViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelDetails")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelDetails"),
|
||||||
|
align: "left",
|
||||||
|
value: "travelDetails"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelUserID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelUserID"),
|
||||||
|
align: "left",
|
||||||
|
value: "userViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemTravelNoChargeQuantity")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemTravelNoChargeQuantity"),
|
||||||
|
align: "right",
|
||||||
|
value: "noChargeQuantity"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "TravelUnitOfMeasureViz")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitOfMeasure"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitOfMeasureViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelCostViz") &&
|
||||||
|
this.value.userCanViewLaborOrTravelRateCosts &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Cost"),
|
||||||
|
align: "right",
|
||||||
|
value: "costViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelListPriceViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("ListPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "listPriceViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelPriceOverride") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("PriceOverride"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceOverride"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelPriceViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Price"),
|
||||||
|
align: "right",
|
||||||
|
value: "priceViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemTravelTaxRateSaleID") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Tax"),
|
||||||
|
align: "left",
|
||||||
|
value: "taxCodeViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelNetViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("NetPrice"),
|
||||||
|
align: "right",
|
||||||
|
value: "netViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelTaxAViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxAAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxAViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelTaxBViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("TaxBAmt"),
|
||||||
|
align: "right",
|
||||||
|
value: "taxBViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "TravelLineTotalViz") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("LineTotal"),
|
||||||
|
align: "right",
|
||||||
|
value: "lineTotalViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].travels.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
travelStartDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.travelStartDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
travelStopDate: window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.travelStopDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
),
|
||||||
|
|
||||||
|
travelRateQuantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.travelRateQuantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
travelRateViz: x.travelRateViz,
|
||||||
|
userViz: x.userViz,
|
||||||
|
noChargeQuantity: window.$gz.locale.decimalLocalized(
|
||||||
|
x.noChargeQuantity,
|
||||||
|
this.pvm.languageName
|
||||||
|
),
|
||||||
|
unitOfMeasureViz: x.unitOfMeasureViz,
|
||||||
|
costViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.costViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
listPriceViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.listPriceViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
priceViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxCodeViz: x.taxCodeViz,
|
||||||
|
priceOverride: window.$gz.locale.currencyLocalized(
|
||||||
|
x.priceOverride,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
netViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.netViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxAViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxAViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
taxBViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.taxBViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
lineTotalViz: window.$gz.locale.currencyLocalized(
|
||||||
|
x.lineTotalViz,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.currencyName
|
||||||
|
),
|
||||||
|
travelDetails: window.$gz.util.truncateString(
|
||||||
|
x.travelDetails,
|
||||||
|
this.pvm.maxTableNotesLength
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].travels.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return this.activeItemIndex != null && this.pvm.rights.change;
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
850
ayanova/src/components/quote-item-units.vue
Normal file
850
ayanova/src/components/quote-item-units.vue
Normal file
@@ -0,0 +1,850 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="value != null" class="mt-8">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-menu offset-y max-width="600px">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<div class="text-h6">
|
||||||
|
<v-icon large :color="hasData ? 'primary' : null" class="mr-2"
|
||||||
|
>$ayiFan</v-icon
|
||||||
|
>
|
||||||
|
{{ $ay.t("WorkOrderItemUnitList") }}
|
||||||
|
<v-btn v-if="!parentDeleted" large icon v-bind="attrs" v-on="on">
|
||||||
|
<v-icon small color="primary">$ayiEllipsisV</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item v-if="canAdd" @click="newItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiPlus</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("New") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canAdd" @click="showBulkUnitsDialog()">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiFan</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("AddMultipleUnits")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && isDeleted" @click="unDeleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashRestoreAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("Undelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDelete && !isDeleted" @click="deleteItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiTrashAlt</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{ $ay.t("SoftDelete") }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item v-if="canDeleteAll" @click="deleteAllItem">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>$ayiDumpster</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
$ay.t("SoftDeleteAll")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<template v-if="hasData">
|
||||||
|
<!-- ############################################################### -->
|
||||||
|
<v-col cols="12" class="mb-10">
|
||||||
|
<v-data-table
|
||||||
|
:headers="headerList"
|
||||||
|
:items="itemList"
|
||||||
|
item-key="index"
|
||||||
|
v-model="selectedRow"
|
||||||
|
class="elevation-1"
|
||||||
|
disable-pagination
|
||||||
|
disable-filtering
|
||||||
|
disable-sort
|
||||||
|
hide-default-footer
|
||||||
|
data-cy="unitsTable"
|
||||||
|
dense
|
||||||
|
:item-class="itemRowClasses"
|
||||||
|
@click:row="handleRowClick"
|
||||||
|
:show-select="$vuetify.breakpoint.xs"
|
||||||
|
single-select
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-col>
|
||||||
|
</template>
|
||||||
|
<template v-if="hasData && hasSelection">
|
||||||
|
<div ref="unittopform"></div>
|
||||||
|
<v-btn
|
||||||
|
v-if="canDelete && isDeleted"
|
||||||
|
large
|
||||||
|
@click="unDeleteItem"
|
||||||
|
color="primary"
|
||||||
|
>{{ $ay.t("Undelete")
|
||||||
|
}}<v-icon right large>$ayiTrashRestoreAlt</v-icon></v-btn
|
||||||
|
>
|
||||||
|
<v-col
|
||||||
|
v-if="form().showMe(this, 'WorkOrderItemUnit')"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().Unit"
|
||||||
|
:variant="'customerid:' + value.customerId"
|
||||||
|
:show-edit-icon="!value.userIsRestrictedType"
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].units[activeItemIndex].unitId
|
||||||
|
"
|
||||||
|
:readonly="
|
||||||
|
formState.readOnly || isDeleted || value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('Unit')"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
|
||||||
|
"
|
||||||
|
data-cy="units.unitId"
|
||||||
|
:rules="[
|
||||||
|
form().required(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
|
||||||
|
)
|
||||||
|
]"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].unitId`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@update:name="unitChange"
|
||||||
|
></gz-pick-list>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'UnitWarrantyInfo') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
sm="6"
|
||||||
|
lg="4"
|
||||||
|
xl="3"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>{{ $ay.t("UnitWarrantyInfo") }}</v-card-title>
|
||||||
|
<v-card-text
|
||||||
|
v-html="
|
||||||
|
value.items[activeWoItemIndex].units[activeItemIndex]
|
||||||
|
.warrantyViz
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="primary" text @click="getWarrantyInfo">{{
|
||||||
|
$ay.t("Search")
|
||||||
|
}}</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemUnitNotes') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<v-textarea
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].units[activeItemIndex].notes
|
||||||
|
"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:disabled="isDeleted"
|
||||||
|
:label="$ay.t('WorkOrderItemUnitNotes')"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`"
|
||||||
|
data-cy="unitUnitNotes"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].notes`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
auto-grow
|
||||||
|
></v-textarea>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemUnitTags') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<gz-tag-picker
|
||||||
|
v-model="value.items[activeWoItemIndex].units[activeItemIndex].tags"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
data-cy="unitTags"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].tags`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-tag-picker>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col v-if="!value.userIsRestrictedType" cols="12">
|
||||||
|
<gz-custom-fields
|
||||||
|
v-model="
|
||||||
|
value.items[activeWoItemIndex].units[activeItemIndex].customFields
|
||||||
|
"
|
||||||
|
:form-key="formCustomTemplateKey"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:parent-v-m="this"
|
||||||
|
key-start-with="WorkOrderItemUnitCustom"
|
||||||
|
:ref="
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
|
||||||
|
"
|
||||||
|
data-cy="unitCustomFields"
|
||||||
|
:error-messages="
|
||||||
|
form().serverErrors(
|
||||||
|
this,
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].customFields`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-custom-fields>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemUnitWiki') &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<gz-wiki
|
||||||
|
:aya-type="$ay.ayt().WorkOrderItem"
|
||||||
|
:aya-id="value.id"
|
||||||
|
:ref="`Items[${activeWoItemIndex}].units[${activeItemIndex}].wiki`"
|
||||||
|
v-model="value.items[activeWoItemIndex].units[activeItemIndex].wiki"
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
@input="
|
||||||
|
fieldValueChanged(
|
||||||
|
`Items[${activeWoItemIndex}].units[${activeItemIndex}].wiki`
|
||||||
|
)
|
||||||
|
"
|
||||||
|
></gz-wiki
|
||||||
|
></v-col>
|
||||||
|
|
||||||
|
<v-col
|
||||||
|
v-if="
|
||||||
|
form().showMe(this, 'WorkOrderItemUnitAttachments') &&
|
||||||
|
value.id &&
|
||||||
|
!value.userIsRestrictedType
|
||||||
|
"
|
||||||
|
cols="12"
|
||||||
|
>
|
||||||
|
<gz-attachments
|
||||||
|
:readonly="formState.readOnly"
|
||||||
|
:aya-type="$ay.ayt().WorkOrderItemUnit"
|
||||||
|
:aya-id="value.items[activeWoItemIndex].units[activeItemIndex].id"
|
||||||
|
></gz-attachments
|
||||||
|
></v-col>
|
||||||
|
</template>
|
||||||
|
</v-row>
|
||||||
|
<!-- ################################################################################-->
|
||||||
|
<!-- ########################## BULK ADD UNITS FORM ###############################-->
|
||||||
|
<!-- ################################################################################-->
|
||||||
|
<template>
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-dialog persistent max-width="600px" v-model="bulkUnitsDialog">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>{{ $ay.t("AddMultipleUnits") }}</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<gz-tag-picker v-model="selectedBulkUnitTags"></gz-tag-picker>
|
||||||
|
<gz-pick-list
|
||||||
|
:aya-type="$ay.ayt().Customer"
|
||||||
|
:show-edit-icon="false"
|
||||||
|
v-model="selectedBulkUnitCustomer"
|
||||||
|
:label="$ay.t('Customer')"
|
||||||
|
:can-clear="true"
|
||||||
|
></gz-pick-list>
|
||||||
|
|
||||||
|
<v-data-table
|
||||||
|
dense
|
||||||
|
v-model="selectedBulkUnits"
|
||||||
|
:headers="bulkUnitTableHeaders"
|
||||||
|
:items="availableBulkUnits"
|
||||||
|
class="my-10"
|
||||||
|
:disable-filtering="true"
|
||||||
|
hide-default-footer
|
||||||
|
:no-data-text="$ay.t('NoData')"
|
||||||
|
show-select
|
||||||
|
item-key="unitId"
|
||||||
|
>
|
||||||
|
</v-data-table>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-btn text @click="bulkUnitsDialog = false" color="primary">{{
|
||||||
|
$ay.t("Cancel")
|
||||||
|
}}</v-btn>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
:disabled="selectedBulkUnitTags.length == 0"
|
||||||
|
color="primary"
|
||||||
|
text
|
||||||
|
@click="bulkUnitsSearch()"
|
||||||
|
>{{ $ay.t("Search") }}</v-btn
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
:disabled="selectedBulkUnits.length == 0"
|
||||||
|
color="primary"
|
||||||
|
text
|
||||||
|
@click="addSelectedBulkUnits()"
|
||||||
|
>{{ $ay.t("Add") }}</v-btn
|
||||||
|
>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeItemIndex: null,
|
||||||
|
selectedRow: [],
|
||||||
|
bulkUnitsDialog: false,
|
||||||
|
selectedBulkUnitCustomer: this.value.customerId,
|
||||||
|
availableBulkUnits: [],
|
||||||
|
selectedBulkUnits: [],
|
||||||
|
selectedBulkUnitTags: [],
|
||||||
|
bulkUnitTableHeaders: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
activeWoItemIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
gotoIndex: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
addNew: {
|
||||||
|
default: null,
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
activeWoItemIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
this.setDefaultView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gotoIndex(val, oldVal) {
|
||||||
|
if (val != oldVal) {
|
||||||
|
let gotoIndex = val;
|
||||||
|
if (val < 0) {
|
||||||
|
//it's a create request
|
||||||
|
gotoIndex = this.newItem();
|
||||||
|
}
|
||||||
|
this.selectedRow = [{ index: gotoIndex }];
|
||||||
|
this.activeItemIndex = gotoIndex;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const el = this.$refs.unittopform;
|
||||||
|
if (el) {
|
||||||
|
el.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async updateContractIfApplicable() {
|
||||||
|
const id = this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].unitId;
|
||||||
|
if (!id || id == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let res = await window.$gz.api.get(`unit/active-contract/${id}`);
|
||||||
|
if (res.error) {
|
||||||
|
window.$gz.eventBus.$emit(
|
||||||
|
"notify-warning",
|
||||||
|
window.$gz.errorHandler.errorToString(res, this)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (res.data.id == 0) {
|
||||||
|
//no contract, just bail
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//has contract, if it differs from main work order contract then offer to set it
|
||||||
|
if (res.data.id == this.value.contractId) {
|
||||||
|
//same contract, just bail
|
||||||
|
//yes the date could not be different but we're not going to pick that nit, they can just unset and set if it matters
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Prompt user to use new contract
|
||||||
|
const prompt = this.$ay
|
||||||
|
.t("ApplyUnitContract")
|
||||||
|
.replace("{0}", res.data.name);
|
||||||
|
|
||||||
|
let dialogResult = await window.$gz.dialog.confirmGenericPreTranslated(
|
||||||
|
prompt,
|
||||||
|
"question"
|
||||||
|
);
|
||||||
|
if (dialogResult == false) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.value.contractId = res.data.id;
|
||||||
|
this.value.isDirty = true;
|
||||||
|
this.pvm.formState.dirty = true;
|
||||||
|
this.$emit("change");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getWarrantyInfo() {
|
||||||
|
this.warrantyInfo = null;
|
||||||
|
|
||||||
|
const id = this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].unitId;
|
||||||
|
if (!id || id == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let res = await window.$gz.api.get(`unit/service-warranty-info/${id}`);
|
||||||
|
if (res.error) {
|
||||||
|
window.$gz.eventBus.$emit(
|
||||||
|
"notify-warning",
|
||||||
|
window.$gz.errorHandler.errorToString(res, this)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
/* {
|
||||||
|
"recentWorkOrders":[{"serial":10,"id":10,"serviceDate":"2021-01-19T22:00:00Z"},{"serial":8,"id":8,"serviceDate":"2021-04-08T22:00:00Z"},{"serial":7,"id":7,"serviceDate":"2021-04-18T20:00:00Z"}],
|
||||||
|
"purchaseDate":"2019-03-12T09:37:52.930923Z",
|
||||||
|
"purchasedFromVendor":null,
|
||||||
|
"purchaseFromVendorId":null,
|
||||||
|
"purchaseReceiptNumber":"139736",
|
||||||
|
"lifeTimeWarranty":false,
|
||||||
|
"warrantyExpiryDate":"2019-04-12T09:37:52.930923Z",
|
||||||
|
"warrantyTerms":"Shipping parts and service"}
|
||||||
|
|
||||||
|
"UnitPurchasedDate": "Purchased Date",
|
||||||
|
"UnitPurchaseFromID": "Purchased From",
|
||||||
|
"UnitReceipt": "Receipt Number",
|
||||||
|
*/
|
||||||
|
const r = res.data;
|
||||||
|
|
||||||
|
let WarrantyInfo = `${this.$ay.t("Warranty")}: `;
|
||||||
|
let WarrantyExpiryInfo = "-";
|
||||||
|
if (r.lifeTimeWarranty) {
|
||||||
|
WarrantyExpiryInfo = this.$ay.t("UnitModelLifeTimeWarranty");
|
||||||
|
} else {
|
||||||
|
if (r.warrantyExpiryDate) {
|
||||||
|
WarrantyExpiryInfo = `${this.$ay.t(
|
||||||
|
"WarrantyExpires"
|
||||||
|
)}: ${window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
r.warrantyExpiryDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WarrantyInfo += WarrantyExpiryInfo;
|
||||||
|
|
||||||
|
let PurchasedFrom = "-";
|
||||||
|
if (r.purchaseFromVendorId) {
|
||||||
|
PurchasedFrom = `<a href="/vendors/${r.purchaseFromVendorId}"> ${r.purchasedFromVendor}</a>`;
|
||||||
|
}
|
||||||
|
let PurchasedDate = "-";
|
||||||
|
if (r.purchaseDate) {
|
||||||
|
PurchasedDate = window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
r.purchaseDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let PurchaseInfo = `${this.$ay.t(
|
||||||
|
"UnitPurchaseFromID"
|
||||||
|
)}: ${PurchasedFrom}<br/>${this.$ay.t(
|
||||||
|
"UnitPurchasedDate"
|
||||||
|
)}: ${PurchasedDate}<br/>${this.$ay.t(
|
||||||
|
"UnitReceipt"
|
||||||
|
)}: ${r.purchaseReceiptNumber ?? "-"}`;
|
||||||
|
|
||||||
|
let RecentWorkOrderList = "";
|
||||||
|
if (r.recentWorkOrders.length > 0) {
|
||||||
|
RecentWorkOrderList += "<br/>";
|
||||||
|
r.recentWorkOrders.forEach(x => {
|
||||||
|
RecentWorkOrderList += `<a href="/svc-workorders/${x.id}"> ${
|
||||||
|
x.serial
|
||||||
|
}<span class='ml-5'>${window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
x.serviceDate,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
)}</span></a><br/>`;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
RecentWorkOrderList = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
let RecentWorkOrderInfo = `${this.$ay.t(
|
||||||
|
"RecentWorkOrders"
|
||||||
|
)}:${RecentWorkOrderList}`;
|
||||||
|
|
||||||
|
let d = `<div>${WarrantyInfo}<br/>${PurchaseInfo}<br/>${RecentWorkOrderInfo}</div>`;
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].warrantyViz = d;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showBulkUnitsDialog() {
|
||||||
|
if (this.bulkUnitTableHeaders.length == 0) {
|
||||||
|
//init bulk table headers
|
||||||
|
this.bulkUnitTableHeaders = [
|
||||||
|
{ text: this.$ay.t("Customer"), value: "customerName" },
|
||||||
|
{ text: this.$ay.t("Unit"), value: "unitSerial" }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
this.bulkUnitsDialog = true;
|
||||||
|
},
|
||||||
|
async bulkUnitsSearch() {
|
||||||
|
this.selectedBulkUnits.splice(0);
|
||||||
|
this.availableBulkUnits.splice(0);
|
||||||
|
|
||||||
|
let res = await window.$gz.api.post(`unit/bulk-add-selection-list`, {
|
||||||
|
tags: this.selectedBulkUnitTags,
|
||||||
|
restrictToCustomerId: this.selectedBulkUnitCustomer
|
||||||
|
});
|
||||||
|
if (res.error) {
|
||||||
|
window.$gz.eventBus.$emit(
|
||||||
|
"notify-warning",
|
||||||
|
window.$gz.errorHandler.errorToString(res, this)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.availableBulkUnits = res.data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addSelectedBulkUnits() {
|
||||||
|
if (this.selectedBulkUnits.length > 0) {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].units.length;
|
||||||
|
this.selectedBulkUnits.forEach(z => {
|
||||||
|
newIndex++;
|
||||||
|
this.value.items[this.activeWoItemIndex].units.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
wiki: null,
|
||||||
|
customFields: "{}",
|
||||||
|
tags: [],
|
||||||
|
notes: null,
|
||||||
|
unitId: z.unitId, //zero to break rule on new
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
unitViz: z.unitSerial,
|
||||||
|
warrantyViz: null
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
}
|
||||||
|
this.bulkUnitsDialog = false;
|
||||||
|
},
|
||||||
|
async unitChange(newName) {
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].unitViz = newName;
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].warrantyViz = null;
|
||||||
|
await this.updateContractIfApplicable();
|
||||||
|
},
|
||||||
|
newItem() {
|
||||||
|
let newIndex = this.value.items[this.activeWoItemIndex].units.length;
|
||||||
|
// {
|
||||||
|
// "0": {
|
||||||
|
// "id": 53,
|
||||||
|
// "concurrency": 9586762,
|
||||||
|
// "notes": "Aut modi molestias molestiae ipsa id.",
|
||||||
|
// "wiki": null,
|
||||||
|
// "customFields": null,
|
||||||
|
// "tags": [],
|
||||||
|
// "unitId": 4,
|
||||||
|
// "unitViz": "83429560",
|
||||||
|
// "quoteItemId": 22
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
this.value.items[this.activeWoItemIndex].units.push({
|
||||||
|
id: 0,
|
||||||
|
concurrency: 0,
|
||||||
|
wiki: null,
|
||||||
|
customFields: "{}",
|
||||||
|
tags: [],
|
||||||
|
notes: null,
|
||||||
|
unitId: 0, //zero to break rule on new
|
||||||
|
isDirty: true,
|
||||||
|
quoteItemId: this.value.items[this.activeWoItemIndex].id,
|
||||||
|
uid: Date.now(),
|
||||||
|
unitViz: null,
|
||||||
|
warrantyViz: null
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$emit("change");
|
||||||
|
this.selectedRow = [{ index: newIndex }];
|
||||||
|
this.activeItemIndex = newIndex;
|
||||||
|
//trigger rule breaking / validation
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].unitId = null;
|
||||||
|
this.fieldValueChanged(
|
||||||
|
`Items[${this.activeWoItemIndex}].units[${this.activeItemIndex}].unitId`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return newIndex; //for create new on goto
|
||||||
|
},
|
||||||
|
unDeleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = false;
|
||||||
|
this.setDefaultView();
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].deleted = true;
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
deleteAllItem() {
|
||||||
|
this.value.items[this.activeWoItemIndex].units.forEach(
|
||||||
|
z => (z.deleted = true)
|
||||||
|
);
|
||||||
|
this.setDefaultView();
|
||||||
|
this.$emit("change");
|
||||||
|
},
|
||||||
|
setDefaultView: function() {
|
||||||
|
//if only one record left then display it otherwise just let the datatable show what the user can click on
|
||||||
|
if (this.value.items[this.activeWoItemIndex].units.length == 1) {
|
||||||
|
this.selectedRow = [{ index: 0 }];
|
||||||
|
this.activeItemIndex = 0;
|
||||||
|
} else {
|
||||||
|
this.selectedRow = [];
|
||||||
|
this.activeItemIndex = null; //select nothing in essence resetting a child selects and this one too clearing form
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleRowClick: function(item) {
|
||||||
|
this.activeItemIndex = item.index;
|
||||||
|
this.selectedRow = [{ index: item.index }];
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.formState.loading && !this.formState.readonly) {
|
||||||
|
//flag this record dirty so it gets picked up by save
|
||||||
|
this.value.items[this.activeWoItemIndex].units[
|
||||||
|
this.activeItemIndex
|
||||||
|
].isDirty = true;
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
|
||||||
|
// //set viz if applicable
|
||||||
|
// if(ref==""){
|
||||||
|
// let selectedPartWarehouse = vm.$refs.partWarehouseId.getFullSelectionValue();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemRowClasses: function(item) {
|
||||||
|
let ret = "";
|
||||||
|
const isDeleted =
|
||||||
|
this.value.items[this.activeWoItemIndex].units[item.index].deleted ===
|
||||||
|
true;
|
||||||
|
|
||||||
|
const hasError = this.form().childRowHasError(
|
||||||
|
this,
|
||||||
|
`Items[${this.activeWoItemIndex}].Units[${item.index}].`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDeleted) {
|
||||||
|
ret += this.form().tableRowDeletedClass();
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
ret += this.form().tableRowErrorClass();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isDeleted: function() {
|
||||||
|
if (
|
||||||
|
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex] ==
|
||||||
|
null
|
||||||
|
) {
|
||||||
|
this.setDefaultView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
this.value.items[this.activeWoItemIndex].units[this.activeItemIndex]
|
||||||
|
.deleted === true
|
||||||
|
);
|
||||||
|
},
|
||||||
|
parentDeleted: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].deleted === true;
|
||||||
|
},
|
||||||
|
|
||||||
|
headerList: function() {
|
||||||
|
/*
|
||||||
|
If the column is a text, left-align it
|
||||||
|
If the column is a number or number + unit, (or date) right-align it (like excel)
|
||||||
|
*/
|
||||||
|
let headers = [];
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "WorkOrderItemUnit")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("Unit"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "UnitModelModelNumber")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitModelModelNumber"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitModelModelNumberViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.form().showMe(this, "UnitModelVendorID")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitModelVendorID"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitModelVendorViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "UnitModelName")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitModelName"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitModelNameViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form().showMe(this, "UnitDescription")) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("UnitDescription"),
|
||||||
|
align: "left",
|
||||||
|
value: "unitDescriptionViz"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.form().showMe(this, "WorkOrderItemUnitNotes") &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
) {
|
||||||
|
headers.push({
|
||||||
|
text: this.$ay.t("WorkOrderItemUnitNotes"),
|
||||||
|
align: "left",
|
||||||
|
value: "notes"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
},
|
||||||
|
itemList: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].units.map((x, i) => {
|
||||||
|
return {
|
||||||
|
index: i,
|
||||||
|
id: x.id,
|
||||||
|
unitViz: x.unitViz,
|
||||||
|
unitModelModelNumberViz: x.unitModelModelNumberViz,
|
||||||
|
unitModelVendorViz: x.unitModelVendorViz,
|
||||||
|
unitModelNameViz: x.unitModelNameViz,
|
||||||
|
unitDescriptionViz: x.unitDescriptionViz,
|
||||||
|
notes: window.$gz.util.truncateString(
|
||||||
|
x.notes,
|
||||||
|
this.pvm.maxTableNotesLength
|
||||||
|
)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formState: function() {
|
||||||
|
return this.pvm.formState;
|
||||||
|
},
|
||||||
|
formCustomTemplateKey: function() {
|
||||||
|
return this.pvm.formCustomTemplateKey;
|
||||||
|
},
|
||||||
|
hasData: function() {
|
||||||
|
return this.value.items[this.activeWoItemIndex].units.length > 0;
|
||||||
|
},
|
||||||
|
hasSelection: function() {
|
||||||
|
return this.activeItemIndex != null;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
},
|
||||||
|
canDelete: function() {
|
||||||
|
return (
|
||||||
|
this.activeItemIndex != null &&
|
||||||
|
this.canDeleteAll &&
|
||||||
|
!this.value.userIsRestrictedType
|
||||||
|
);
|
||||||
|
},
|
||||||
|
canDeleteAll: function() {
|
||||||
|
return this.pvm.rights.change && !this.value.userIsRestrictedType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -888,7 +888,7 @@ export default {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.pvm.washWorkOrderItem(wi);
|
this.pvm.washWorkOrderItem(wi);
|
||||||
wi.workOrderId = this.value.id;
|
wi.quoteId = this.value.id;
|
||||||
wi.sequence = newIndex + 1;
|
wi.sequence = newIndex + 1;
|
||||||
this.value.items.push(wi);
|
this.value.items.push(wi);
|
||||||
this.$emit("change");
|
this.$emit("change");
|
||||||
@@ -931,7 +931,7 @@ export default {
|
|||||||
wiki: null,
|
wiki: null,
|
||||||
customFields: "{}",
|
customFields: "{}",
|
||||||
tags: [],
|
tags: [],
|
||||||
workOrderId: this.value.id,
|
quoteId: this.value.id,
|
||||||
techNotes: null,
|
techNotes: null,
|
||||||
workorderItemStatusId: null,
|
workorderItemStatusId: null,
|
||||||
workorderItemPriorityId: null,
|
workorderItemPriorityId: null,
|
||||||
|
|||||||
299
ayanova/src/components/quote-state.vue
Normal file
299
ayanova/src/components/quote-state.vue
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="mb-n2 ml-10">
|
||||||
|
<span class="text-caption">{{ $ay.t("QuoteQuoteStatusType") }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="mb-6 mb-sm-0">
|
||||||
|
<v-btn icon class="ml-n1 mr-2" @click="openDialog = true">
|
||||||
|
<v-icon>{{ openIcon() }}</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<span class="text-h6" @click="openDialog = true">{{
|
||||||
|
pvm.currentState.name
|
||||||
|
}}</span>
|
||||||
|
<v-icon :color="pvm.currentState.color" class="ml-4">$ayiFlag</v-icon>
|
||||||
|
<v-icon color="primary" v-if="pvm.currentState.locked" class="ml-4"
|
||||||
|
>$ayiLock</v-icon
|
||||||
|
>
|
||||||
|
<v-icon color="primary" v-if="pvm.currentState.completed" class="ml-4"
|
||||||
|
>$ayiCheckCircle</v-icon
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-dialog v-model="openDialog" max-width="600px">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
<span class="text-h5">{{ $ay.t("QuoteQuoteStatusType") }}</span>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<template v-if="$vuetify.breakpoint.smAndUp">
|
||||||
|
<!-- WIDE VIEW -->
|
||||||
|
<div v-for="item in stateDisplayList" :key="item.id">
|
||||||
|
<span>{{ item.timeStamp }}</span>
|
||||||
|
<span class="ml-3">{{ item.user }}</span>
|
||||||
|
<span class="font-weight-bold ml-3">{{ item.name }}</span>
|
||||||
|
<v-icon small :color="item.color" class="ml-4">$ayiFlag</v-icon>
|
||||||
|
<v-icon small color="primary" v-if="item.locked" class="ml-4"
|
||||||
|
>$ayiLock</v-icon
|
||||||
|
>
|
||||||
|
<v-icon small color="primary" v-if="item.completed" class="ml-4"
|
||||||
|
>$ayiCheckCircle</v-icon
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<!-- NARROW VIEW -->
|
||||||
|
<div v-for="item in stateDisplayList" :key="item.id">
|
||||||
|
<span>{{ item.timeStamp }} </span>
|
||||||
|
<span>{{ item.user }}</span>
|
||||||
|
<div class="mb-2">
|
||||||
|
<span class="font-weight-bold">{{ item.name }}</span>
|
||||||
|
<v-icon small :color="item.color" class="ml-4"
|
||||||
|
>$ayiFlag</v-icon
|
||||||
|
>
|
||||||
|
<v-icon small color="primary" v-if="item.locked" class="ml-4"
|
||||||
|
>$ayiLock</v-icon
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
small
|
||||||
|
color="primary"
|
||||||
|
v-if="item.completed"
|
||||||
|
class="ml-4"
|
||||||
|
>$ayiCheckCircle</v-icon
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- append-outer-icon="$ayiPlus"
|
||||||
|
@click:append-outer="addState()" -->
|
||||||
|
<template v-if="canAdd">
|
||||||
|
<div class="mt-8">
|
||||||
|
<v-autocomplete
|
||||||
|
v-model="selectedStatus"
|
||||||
|
:items="pvm.selectLists.allowedquotestatus"
|
||||||
|
item-text="name"
|
||||||
|
item-value="id"
|
||||||
|
dense
|
||||||
|
:label="$ay.t('NewStatus')"
|
||||||
|
prepend-icon="$ayiEdit"
|
||||||
|
@click:prepend="handleEditStateClick()"
|
||||||
|
>
|
||||||
|
<template v-slot:item="data">
|
||||||
|
<v-list-item-avatar>
|
||||||
|
<v-icon :color="data.item.color">$ayiFlag</v-icon>
|
||||||
|
</v-list-item-avatar>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title
|
||||||
|
><span class="text-subtitle-2">{{
|
||||||
|
data.item.name
|
||||||
|
}}</span
|
||||||
|
><v-icon
|
||||||
|
small
|
||||||
|
color="disabled"
|
||||||
|
class="ml-2"
|
||||||
|
v-if="data.item.locked"
|
||||||
|
>$ayiLock</v-icon
|
||||||
|
>
|
||||||
|
<v-icon
|
||||||
|
color="disabled"
|
||||||
|
class="ml-1"
|
||||||
|
small
|
||||||
|
v-if="data.item.completed"
|
||||||
|
>$ayiCheckCircle</v-icon
|
||||||
|
></v-list-item-title
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-list-item-subtitle>
|
||||||
|
{{ data.item.notes }}</v-list-item-subtitle
|
||||||
|
>
|
||||||
|
</v-list-item-content>
|
||||||
|
<v-list-item-action> </v-list-item-action>
|
||||||
|
</template>
|
||||||
|
</v-autocomplete>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="blue darken-1" text @click="cancelDialog()">{{
|
||||||
|
$ay.t("Cancel")
|
||||||
|
}}</v-btn>
|
||||||
|
<v-btn
|
||||||
|
color="blue darken-1"
|
||||||
|
:disabled="selectedStatus == null"
|
||||||
|
text
|
||||||
|
@click="save()"
|
||||||
|
>{{ $ay.t("OK") }}</v-btn
|
||||||
|
>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/* XXXeslint-disable */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedStatus: null,
|
||||||
|
openDialog: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
pvm: {
|
||||||
|
default: null,
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
allStates: {
|
||||||
|
default: null,
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
allowedStates: {
|
||||||
|
default: null,
|
||||||
|
type: Array
|
||||||
|
},
|
||||||
|
formKey: { type: String, default: "" }, //used to grab template from store
|
||||||
|
readonly: Boolean,
|
||||||
|
disabled: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
addState() {
|
||||||
|
if (this.selectedStatus != null) {
|
||||||
|
//first remove any other non saved states in collection, no need to send them to the server if there was multiple state changes since last save
|
||||||
|
this.value.states = this.value.states.filter(
|
||||||
|
z => z.concurrency != null
|
||||||
|
);
|
||||||
|
|
||||||
|
//is it a different state?
|
||||||
|
if (this.selectedStatus == this.pvm.currentState.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//push in new state
|
||||||
|
this.value.states.push({
|
||||||
|
quoteId: this.value.id,
|
||||||
|
quoteStatusId: this.selectedStatus,
|
||||||
|
userId: window.$gz.store.state.userId,
|
||||||
|
userViz: window.$gz.store.state.userName,
|
||||||
|
created: window.$gz.locale.nowUTC8601String()
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectedStatus = null;
|
||||||
|
this.pvm.formState.dirty = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getStateForDisplay(state) {
|
||||||
|
let ret = {
|
||||||
|
id: Date.now,
|
||||||
|
name: "??",
|
||||||
|
color: "#ffffff",
|
||||||
|
locked: false,
|
||||||
|
completed: false,
|
||||||
|
timeStamp: "??",
|
||||||
|
user: "??"
|
||||||
|
};
|
||||||
|
const s = this.allStates.find(z => z.id == state.quoteStatusId);
|
||||||
|
if (s == null) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//make for display
|
||||||
|
ret.id = state.id;
|
||||||
|
ret.name = s.name;
|
||||||
|
ret.color = s.color;
|
||||||
|
ret.locked = s.locked;
|
||||||
|
ret.completed = s.completed;
|
||||||
|
ret.user = state.userViz;
|
||||||
|
ret.timeStamp = window.$gz.locale.utcDateToShortDateAndTimeLocalized(
|
||||||
|
state.created,
|
||||||
|
this.pvm.timeZoneName,
|
||||||
|
this.pvm.languageName,
|
||||||
|
this.pvm.hour12
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
form() {
|
||||||
|
return window.$gz.form;
|
||||||
|
},
|
||||||
|
openIcon: function() {
|
||||||
|
if (this.canAdd) {
|
||||||
|
return "$ayiEdit";
|
||||||
|
}
|
||||||
|
return "$ayiHistory";
|
||||||
|
},
|
||||||
|
handleEditStateClick: function() {
|
||||||
|
window.$gz.eventBus.$emit("openobject", {
|
||||||
|
type: window.$gz.type.QuoteStatus,
|
||||||
|
id: this.selectedStatus
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
this.addState();
|
||||||
|
this.openDialog = false;
|
||||||
|
},
|
||||||
|
cancelDialog() {
|
||||||
|
this.selectedStatus = null;
|
||||||
|
this.openDialog = false;
|
||||||
|
},
|
||||||
|
fieldValueChanged(ref) {
|
||||||
|
if (!this.pvm.formState.loading && !this.pvm.formState.readonly) {
|
||||||
|
window.$gz.form.fieldValueChanged(this.pvm, ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
hasState() {
|
||||||
|
return this.value.states != null && this.value.states.length > 0;
|
||||||
|
},
|
||||||
|
stateDisplayList() {
|
||||||
|
let ret = [];
|
||||||
|
this.value.states.forEach(z => {
|
||||||
|
ret.push(this.getStateForDisplay(z));
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
canAdd: function() {
|
||||||
|
//first check most obvious disqualifying properties
|
||||||
|
if (!this.pvm.rights.change) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//not currently locked, user has rights to do it so allow it
|
||||||
|
if (!this.value.isLockedAtServer) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//locked, confirm if user can change it
|
||||||
|
//if any role then no problem
|
||||||
|
|
||||||
|
//ok, only thing left to check is if the current user can unlock this
|
||||||
|
//get remove roles required for current state
|
||||||
|
let cs = this.pvm.currentState;
|
||||||
|
if (cs.removeRoles == null || cs.removeRoles == 0) {
|
||||||
|
//no state set yet
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ok, need to check the role here against current user roles to see if this is valid
|
||||||
|
if (window.$gz.role.hasRole(cs.removeRoles)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -88,7 +88,7 @@ export default {
|
|||||||
let wi = this.$route.params.copyItem;
|
let wi = this.$route.params.copyItem;
|
||||||
if (wi) {
|
if (wi) {
|
||||||
this.washWorkOrderItem(wi);
|
this.washWorkOrderItem(wi);
|
||||||
wi.workOrderId = vm.obj.id;
|
wi.quoteId = vm.obj.id;
|
||||||
wi.sequence = vm.obj.items.length + 1;
|
wi.sequence = vm.obj.items.length + 1;
|
||||||
vm.obj.items.push(wi);
|
vm.obj.items.push(wi);
|
||||||
setDirty = true;
|
setDirty = true;
|
||||||
@@ -104,7 +104,7 @@ export default {
|
|||||||
this.obj.serial = 0;
|
this.obj.serial = 0;
|
||||||
this.obj.isDirty = true;
|
this.obj.isDirty = true;
|
||||||
vm.obj.items.forEach(z => {
|
vm.obj.items.forEach(z => {
|
||||||
z.workOrderId = 0;
|
z.quoteId = 0;
|
||||||
this.washWorkOrderItem(z);
|
this.washWorkOrderItem(z);
|
||||||
});
|
});
|
||||||
setDirty = true;
|
setDirty = true;
|
||||||
@@ -228,8 +228,8 @@ export default {
|
|||||||
hour12: window.$gz.locale.getHour12(),
|
hour12: window.$gz.locale.getHour12(),
|
||||||
// resetSelections: false,
|
// resetSelections: false,
|
||||||
selectLists: {
|
selectLists: {
|
||||||
wostatus: [],
|
quotestatus: [],
|
||||||
allowedwostatus: [],
|
allowedquotestatus: [],
|
||||||
woItemPriorities: [],
|
woItemPriorities: [],
|
||||||
woItemStatus: [],
|
woItemStatus: [],
|
||||||
woItemTaskCompletionTypes: [],
|
woItemTaskCompletionTypes: [],
|
||||||
@@ -288,8 +288,8 @@ export default {
|
|||||||
//find it in the status collection
|
//find it in the status collection
|
||||||
//and return here
|
//and return here
|
||||||
const laststate = this.obj.states[this.obj.states.length - 1];
|
const laststate = this.obj.states[this.obj.states.length - 1];
|
||||||
const found = this.selectLists.wostatus.find(
|
const found = this.selectLists.quotestatus.find(
|
||||||
z => z.id == laststate.workOrderStatusId
|
z => z.id == laststate.quoteStatusId
|
||||||
);
|
);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
@@ -625,19 +625,19 @@ export default {
|
|||||||
|
|
||||||
wi.expenses.forEach(x => {
|
wi.expenses.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.labors.forEach(x => {
|
wi.labors.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.loans.forEach(x => {
|
wi.loans.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
x.cost = 0;
|
x.cost = 0;
|
||||||
@@ -645,7 +645,7 @@ export default {
|
|||||||
});
|
});
|
||||||
wi.parts.forEach(x => {
|
wi.parts.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
x.cost = 0;
|
x.cost = 0;
|
||||||
@@ -654,31 +654,31 @@ export default {
|
|||||||
|
|
||||||
wi.scheduledUsers.forEach(x => {
|
wi.scheduledUsers.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.tasks.forEach(x => {
|
wi.tasks.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.travels.forEach(x => {
|
wi.travels.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.units.forEach(x => {
|
wi.units.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
wi.outsideServices.forEach(x => {
|
wi.outsideServices.forEach(x => {
|
||||||
x.id = 0;
|
x.id = 0;
|
||||||
x.workOrderItemId = 0;
|
x.quoteItemId = 0;
|
||||||
x.concurrency = undefined;
|
x.concurrency = undefined;
|
||||||
x.isDirty = true;
|
x.isDirty = true;
|
||||||
});
|
});
|
||||||
@@ -732,8 +732,8 @@ async function saveHeader(vm) {
|
|||||||
vm.obj.id = res.data.id;
|
vm.obj.id = res.data.id;
|
||||||
vm.obj.serial = res.data.serial;
|
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 workorder id so they can save
|
||||||
vm.obj.states.forEach(z => (z.workOrderId = vm.obj.id));
|
vm.obj.states.forEach(z => (z.quoteId = vm.obj.id));
|
||||||
vm.obj.items.forEach(z => (z.workOrderId = vm.obj.id));
|
vm.obj.items.forEach(z => (z.quoteId = vm.obj.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1870,7 +1870,7 @@ async function fetchTranslatedText(vm) {
|
|||||||
"WorkOrderInternalReferenceNumber",
|
"WorkOrderInternalReferenceNumber",
|
||||||
"WorkOrderOnsite",
|
"WorkOrderOnsite",
|
||||||
"NewStatus",
|
"NewStatus",
|
||||||
"WorkOrderStatus",
|
"QuoteQuoteStatusType",
|
||||||
"WorkOrderCustom1",
|
"WorkOrderCustom1",
|
||||||
"WorkOrderCustom2",
|
"WorkOrderCustom2",
|
||||||
"WorkOrderCustom3",
|
"WorkOrderCustom3",
|
||||||
@@ -2087,8 +2087,8 @@ async function populateSelectionLists(vm) {
|
|||||||
vm.formState.serverError = res.error;
|
vm.formState.serverError = res.error;
|
||||||
window.$gz.form.setErrorBoxErrors(vm);
|
window.$gz.form.setErrorBoxErrors(vm);
|
||||||
} else {
|
} else {
|
||||||
vm.selectLists.wostatus = res.data.all;
|
vm.selectLists.quotestatus = res.data.all;
|
||||||
vm.selectLists.allowedwostatus = res.data.allowed;
|
vm.selectLists.allowedquotestatus = res.data.allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = await window.$gz.api.get("work-order-item-status/list");
|
res = await window.$gz.api.get("work-order-item-status/list");
|
||||||
|
|||||||
Reference in New Issue
Block a user