This commit is contained in:
2021-03-16 21:59:52 +00:00
parent acf627f1a3
commit 6fadcabe81
3 changed files with 205 additions and 82 deletions

View File

@@ -58,11 +58,18 @@ todo: v8 migrate additions
## CLIENT MISC ITEMS
todo: acc-service-bank is using a decimal control instead of a currency control for currency field
todo: partassembly form should use an edit dialog rather than edit in place in the grid as it's ugly and clunky and outside of the standard that will be used in PO and wo etc
copy from Contract form and use it's technique for immediate viz value sync event
todo: Parts, fractional values?? should anywhere a quantity of part show be a decimal control and if so then should show no trailing zeros like v7?
The correct thing to do is ensure decimal numbers if entered display localized anywhere so bearing that in mind....
(in v7 if you enter 1 it displays as 1 not 1.00, if you enter 1.25 then it displays as 1.25)
right now kind of using a mish mash where in some areas quantities are just raw numbers because I'm testing with integer values for things like parts so no seeing this
but if I force to use decimalLocalized then there are always 2 digits even when it's just .00 which is sort of ugly but sort of not ugly if they use that a lot in which case it would visually line up in grids
not sure what is the best way, maybe a setting? I do see there is a minimum digits for this Intl.NumberFormat(languageName, {minimumFractionDigits: 2}).format(value);
so maybe there's a setting to handle this gracefully??
If so then I need to look back at any place showing fractional values potentially and ensure it's all standardized whatever way
todo: should user required rule (defined in form custom settings) show a variation of the required error message so that it's clear *they* defined it and they can unset it in customize?
right now they could set a required rule, forget they set it then email us to bitch that it shouldn't be required
todo: reports need duration display helper

View File

@@ -247,6 +247,9 @@ Vue.prototype.$ay = {
cur: function(value) {
return locale.currencyLocalized(value);
},
dec: function(value) {
return locale.decimalLocalized(value);
},
util: function() {
return gzutil;
}

View File

@@ -18,69 +18,48 @@
></v-text-field>
</v-col>
<v-col cols="12">
<gz-pick-list
v-if="!formState.readOnly"
v-model="selectedPart"
:aya-type="ayaTypes().Part"
:show-edit-icon="true"
:label="$ay.t('Part')"
ref="partId"
data-cy="partId"
@input="addItem()"
></gz-pick-list>
<v-simple-table class="my-6">
<!-- ################################ PARTS ############################### -->
<v-col cols="12" sm="6" class="mb-10">
<span class="text-subtitle-2"> {{ $ay.t("PartList") }}</span
><v-btn large icon @click="addItem()">
<v-icon small color="primary">$ayiPlus</v-icon>
</v-btn>
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">
{{ $ay.t("PartList") }}
{{ $ay.t("Part") }}
</th>
<th class="text-left">
{{ $ay.t("WorkOrderItemPartQuantity") }}
</th>
<th></th>
</tr>
</thead>
<tbody>
<!-- Note the use of partid which is unique plus quantity, without that quantity Vue doesn't update the display of quantity if it's changed by the quanittyChanged method -->
<tr
v-for="item in sortedList()"
:key="item.partId.toString() + item.quantity.toString()"
>
<td>
<tr v-for="(item, index) in obj.items" :key="item.Id">
<td class="text-left">
{{ item.partViz }}
<template v-if="$vuetify.breakpoint.xs">
<div class="my-3">
<v-icon class="ml-2" @click="openItem(item)">
$ayiEdit
</v-icon>
<v-icon class="ml-6" @click="removeItem(item)">
$ayiTrashAlt
</v-icon>
</div>
</template>
<template v-else>
<v-icon class="ml-2" @click="openItem(item)">
</td>
<th class="text-left">
{{ $ay.dec(item.quantity) }}
</th>
<td class="text-right">
<v-btn large icon @click="editItem(index)" class="ml-4">
<v-icon small>
$ayiEdit
</v-icon>
<v-icon class="ml-6" @click="removeItem(item)">
$ayiTrashAlt
</v-icon>
</template>
</td>
<td>
<gz-decimal
v-model="item.quantity"
:readonly="formState.readOnly"
@input="quantityChanged(item)"
></gz-decimal>
</v-btn>
</td>
</tr>
</tbody>
</template>
</v-simple-table>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<v-checkbox
v-model="obj.active"
@@ -158,6 +137,124 @@
:size="60"
></v-progress-circular>
</template>
<!-- #########################################################################################################-->
<!-- ########################## ITEM EDIT FORM ###############################-->
<!-- #########################################################################################################-->
<template v-if="obj.items.length && editItemIndex != -1">
<v-row justify="center">
<v-dialog v-model="editItemDialog">
<v-card>
<v-card-title> </v-card-title>
<v-card-text>
<v-row>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-pick-list
:allow-no-selection="false"
:can-clear="false"
:aya-type="ayaTypes().Part"
:show-edit-icon="true"
v-model="obj.items[editItemIndex].partId"
:readonly="formState.readOnly"
:label="$ay.t('Part')"
ref="userid"
data-cy="userid"
:rules="[
form().integerValid(this, 'Items.PartId'),
form().required(this, 'Items.PartId')
]"
:error-messages="
form().serverErrors(
this,
`Items[${editItemIndex}].PartId`
)
"
@input="fieldValueChanged(`Items[${editItemIndex}].PartId`)"
:name.sync="obj.items[editItemIndex].partViz"
></gz-pick-list>
</v-col>
<v-col cols="12" sm="6" lg="4" xl="3">
<gz-decimal
v-model="obj.items[editItemIndex].quantity"
:readonly="formState.readOnly"
:label="$ay.t('WorkOrderItemPartQuantity')"
ref="Items.Quantity"
data-cy="Items.Quantity"
:rules="[
form().decimalValid(this, 'Items.Quantity'),
form().required(this, 'Items.Quantity')
]"
:error-messages="
form().serverErrors(
this,
`Items[${editItemIndex}].Quantity`
)
"
@input="
fieldValueChanged(`Items[${editItemIndex}].Quantity`)
"
></gz-decimal>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<template v-if="!$vuetify.breakpoint.xs">
<v-btn color="red darken-1" text @click="deleteItem()">{{
$ay.t("Delete")
}}</v-btn>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="addItem()"
class="ml-4"
>{{ $ay.t("New") }}</v-btn
>
<v-btn
color="blue darken-1"
text
@click="editItemDialog = false"
class="ml-4"
>{{ $ay.t("OK") }}</v-btn
>
</template>
<template v-else>
<!-- MOBILE FORMAT -->
<v-row>
<v-btn
class="mt-4"
block
text
color="blue darken-1"
@click="editItemDialog = false"
>{{ $ay.t("OK") }}</v-btn
>
<v-btn
class="mt-4"
block
text
color="blue darken-1"
@click="addItem()"
>{{ $ay.t("New") }}</v-btn
>
<v-btn
class="mt-8 mb-6"
block
text
color="red darken-1"
@click="deleteItem()"
>{{ $ay.t("Delete") }}</v-btn
>
</v-row>
</template>
</v-card-actions>
</v-card>
</v-dialog>
</v-row>
</template>
</div>
</template>
@@ -254,7 +351,9 @@ export default {
},
rights: window.$gz.role.defaultRightsObject(),
ayaType: window.$gz.type.PartAssembly,
selectedPart: null
selectedPart: null,
editItemDialog: false,
editItemIndex: 0
};
},
//WATCHERS
@@ -293,45 +392,59 @@ export default {
},
methods: {
sortedList: function() {
function compare(a, b) {
if (a.partViz < b.partViz) return -1;
if (a.partViz > b.partViz) return 1;
return 0;
}
return this.obj.items.slice().sort(compare);
},
addItem: function() {
let vm = this;
let selected = vm.$refs.partId.getFullSelectionValue();
if (selected == null || selected.id == null) {
return;
}
let index = vm.obj.items.findIndex(z => z.partId == selected.id);
if (index != -1) {
//already in the list
return;
}
this.editItemIndex =
this.obj.items.push({
id: 0,
partAssemblyId: this.obj.id,
partId: null
}) - 1;
vm.obj.items.push({
partAssemblyId: vm.obj.id,
partId: selected.id,
partViz: selected.name,
quantity: 1
});
this.editItemDialog = true;
this.formState.dirty = true;
},
editItem: function(index) {
this.editItemIndex = index;
this.editItemDialog = true;
},
deleteItem: function() {
this.editItemDialog = false;
this.obj.items.splice(this.editItemIndex, 1);
this.editItemIndex = -1;
this.formState.dirty = true;
},
// editItem: function() {},
// addItem: function() {
// let vm = this;
// let selected = vm.$refs.partId.getFullSelectionValue();
// if (selected == null || selected.id == null) {
// return;
// }
// let index = vm.obj.items.findIndex(z => z.partId == selected.id);
// if (index != -1) {
// //already in the list
// return;
// }
// vm.obj.items.push({
// partAssemblyId: vm.obj.id,
// partId: selected.id,
// partViz: selected.name,
// quantity: 1
// });
// vm.formState.dirty = true;
// },
// removeItem: function(item) {
// let vm = this;
// let index = vm.obj.items.findIndex(z => z.partId == item.partId);
// if (index == -1) {
// return;
// }
// vm.obj.items.splice(index, 1);
// vm.formState.dirty = true;
// },
vm.formState.dirty = true;
},
removeItem: function(item) {
let vm = this;
let index = vm.obj.items.findIndex(z => z.partId == item.partId);
if (index == -1) {
return;
}
vm.obj.items.splice(index, 1);
vm.formState.dirty = true;
},
openItem: function(item) {
window.$gz.eventBus.$emit("openobject", {
type: window.$gz.type.Part,