Add more complete support for ordering batches in mobile
can now see "all" batches, and execute if desired
This commit is contained in:
parent
4d36d003f2
commit
ce7efd3c8b
|
@ -52,6 +52,12 @@ const routes = [
|
||||||
// component: OrderingBatch,
|
// component: OrderingBatch,
|
||||||
// props: {mode: 'editing'},
|
// props: {mode: 'editing'},
|
||||||
// },
|
// },
|
||||||
|
{
|
||||||
|
path: '/ordering/:uuid/execute',
|
||||||
|
name: 'ordering.execute',
|
||||||
|
component: OrderingBatch,
|
||||||
|
props: {mode: 'executing'},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/ordering/rows/:uuid',
|
path: '/ordering/rows/:uuid',
|
||||||
name: 'ordering.rows.view',
|
name: 'ordering.rows.view',
|
||||||
|
|
|
@ -1,120 +1,144 @@
|
||||||
<template>
|
<template>
|
||||||
<byjove-model-crud model-name="PurchaseBatch"
|
<div>
|
||||||
model-index-title="Ordering"
|
<byjove-model-crud v-if="!showingExecutionOptions"
|
||||||
model-title="Ordering Batch"
|
model-name="PurchaseBatch"
|
||||||
model-title-plural="Ordering Batches"
|
model-index-title="Ordering"
|
||||||
model-path-prefix="/ordering"
|
model-title="Ordering Batch"
|
||||||
model-permission-prefix="ordering"
|
model-title-plural="Ordering Batches"
|
||||||
row-path-prefix="/ordering/rows"
|
model-path-prefix="/ordering"
|
||||||
:mode="mode"
|
:mode="mode"
|
||||||
@refresh="record => { batch = record }"
|
@refresh="record => { batch = record }"
|
||||||
api-index-url="/api/ordering-batches"
|
api-index-url="/api/ordering-batches"
|
||||||
api-object-url="/api/ordering-batch/"
|
api-object-url="/api/ordering-batch/"
|
||||||
:header-label-renderer="renderHeaderLabel"
|
:header-label-renderer="renderHeaderLabel"
|
||||||
:allow-edit="false"
|
:allow-edit="false"
|
||||||
has-rows
|
has-rows
|
||||||
api-rows-url="/api/ordering-batch-rows"
|
row-path-prefix="/ordering/rows"
|
||||||
:row-label-renderer="renderRowLabel"
|
api-rows-url="/api/ordering-batch-rows"
|
||||||
:row-route-getter="getRowRoute"
|
:row-label-renderer="renderRowLabel"
|
||||||
save-button-text="Make Ordering Batch"
|
:row-route-getter="getRowRoute"
|
||||||
@save="save">
|
@save="save"
|
||||||
|
save-button-text="Make Ordering Batch"
|
||||||
<div v-if="mode == 'creating'">
|
model-permission-prefix="ordering">
|
||||||
|
<!-- :save-disabled="saveDisabled" -->
|
||||||
|
|
||||||
<b-field label="Vendor"
|
<b-field label="Vendor"
|
||||||
:type="{'is-danger': !batch.vendor_uuid}">
|
:type="{'is-danger': !batch.vendor_uuid}">
|
||||||
<byjove-autocomplete v-model="batch.vendor_uuid"
|
<byjove-autocomplete v-if="mode == 'creating'"
|
||||||
|
v-model="batch.vendor_uuid"
|
||||||
service-url="/api/vendors/autocomplete">
|
service-url="/api/vendors/autocomplete">
|
||||||
</byjove-autocomplete>
|
</byjove-autocomplete>
|
||||||
</b-field>
|
<span v-if="mode != 'creating'">
|
||||||
|
|
||||||
<br />
|
|
||||||
</div> <!-- creating -->
|
|
||||||
|
|
||||||
<div v-if="mode == 'viewing'">
|
|
||||||
|
|
||||||
<b-field label="Vendor">
|
|
||||||
<span>
|
|
||||||
{{ batch.vendor_display }}
|
{{ batch.vendor_display }}
|
||||||
</span>
|
</span>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Date Ordered"
|
<b-field label="Date Ordered"
|
||||||
v-if="mode != 'creating' && batch.executed">
|
v-if="mode == 'viewing' && batch.executed">
|
||||||
<span>
|
<span>{{ batch.date_ordered }}</span>
|
||||||
{{ batch.date_ordered }}
|
|
||||||
</span>
|
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Total">
|
<b-field label="Total"
|
||||||
<span>
|
v-if="mode == 'viewing' || mode == 'executing'">
|
||||||
{{ batch.po_total_calculated_display }}
|
<span>{{ batch.po_total_calculated_display }}</span>
|
||||||
</span>
|
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Created"
|
<div v-if="mode == 'viewing'">
|
||||||
v-if="mode != 'creating' && batch.executed">
|
|
||||||
<span>
|
|
||||||
{{ batch.created }}
|
|
||||||
</span>
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<b-field label="Created By"
|
<b-field label="Created"
|
||||||
v-if="mode != 'creating' && batch.executed">
|
v-if="mode != 'creating' && batch.executed">
|
||||||
<span>
|
|
||||||
{{ batch.created_by_display }}
|
|
||||||
</span>
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<br v-if="!batch.executed" />
|
|
||||||
|
|
||||||
<div v-if="batch.executed">
|
|
||||||
|
|
||||||
<b-field label="Executed">
|
|
||||||
<span>
|
<span>
|
||||||
{{ batch.executed }}
|
{{ batch.created }}
|
||||||
</span>
|
</span>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Executed By">
|
<b-field label="Created By"
|
||||||
|
v-if="mode != 'creating' && batch.executed">
|
||||||
<span>
|
<span>
|
||||||
{{ batch.executed_by_display }}
|
{{ batch.created_by_display }}
|
||||||
</span>
|
</span>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
</div> <!-- executed -->
|
<b-field label="Complete"
|
||||||
|
v-if="mode != 'creating' && batch.complete && !batch.executed">
|
||||||
|
<span>{{ batch.complete }}</span>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
</div> <!-- viewing -->
|
<br v-if="!batch.executed" />
|
||||||
|
|
||||||
<template slot="quick-entry">
|
<div v-if="batch.executed">
|
||||||
<div v-if="mode == 'viewing' && !batch.executed && !batch.complete">
|
|
||||||
<b-input v-model="quickEntry"
|
<b-field label="Executed">
|
||||||
placeholder="Enter UPC"
|
<span>
|
||||||
icon="search"
|
{{ batch.executed }}
|
||||||
@keypress.native="quickKey">
|
</span>
|
||||||
</b-input>
|
</b-field>
|
||||||
|
|
||||||
|
<b-field label="Executed By">
|
||||||
|
<span>
|
||||||
|
{{ batch.executed_by_display }}
|
||||||
|
</span>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
</div> <!-- executed -->
|
||||||
|
|
||||||
|
</div> <!-- viewing -->
|
||||||
|
|
||||||
|
<template slot="quick-entry">
|
||||||
|
<div v-if="mode == 'viewing' && batch.mutable">
|
||||||
|
<b-input v-model="quickEntry"
|
||||||
|
placeholder="Enter UPC"
|
||||||
|
icon="search"
|
||||||
|
@keypress.native="quickKey">
|
||||||
|
</b-input>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="footer"
|
||||||
|
v-if="mode == 'viewing' && !batch.executed">
|
||||||
<br />
|
<br />
|
||||||
</div>
|
<div class="buttons is-centered">
|
||||||
</template>
|
<!-- <b-button v-if="!batch.complete" -->
|
||||||
|
<!-- type="is-primary" -->
|
||||||
|
<!-- @click="editWorksheet()"> -->
|
||||||
|
<!-- Edit as Worksheet -->
|
||||||
|
<!-- </b-button> -->
|
||||||
|
<b-button v-if="!batch.complete"
|
||||||
|
type="is-primary"
|
||||||
|
@click="markOrderingComplete()">
|
||||||
|
Mark Complete
|
||||||
|
</b-button>
|
||||||
|
<b-button v-if="batch.complete"
|
||||||
|
type="is-primary"
|
||||||
|
@click="markOrderingIncomplete()">
|
||||||
|
Mark Incomplete
|
||||||
|
</b-button>
|
||||||
|
<b-button v-if="batch.complete"
|
||||||
|
type="is-primary"
|
||||||
|
tag="router-link"
|
||||||
|
:to="`/ordering/${batch.uuid}/execute`">
|
||||||
|
Execute Batch
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</byjove-model-crud>
|
||||||
|
|
||||||
<template slot="footer"
|
<div v-if="mode == 'executing'">
|
||||||
v-if="mode == 'viewing' && !batch.executed">
|
|
||||||
<br />
|
<br />
|
||||||
<div class="buttons is-centered">
|
<div class="buttons">
|
||||||
<b-button v-if="!batch.complete"
|
<b-button type="is-primary"
|
||||||
type="is-primary"
|
@click="executeBatch()">
|
||||||
@click="editWorksheet()">
|
Submit this Order
|
||||||
Edit as Worksheet
|
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button v-if="!batch.complete"
|
<b-button tag="router-link"
|
||||||
type="is-primary"
|
:to="`/ordering/${batch.uuid}`">
|
||||||
@click="markOrderingComplete()">
|
Cancel
|
||||||
Ordering is Complete!
|
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<b-loading :active="executing"></b-loading>
|
||||||
|
</div>
|
||||||
</byjove-model-crud>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -133,6 +157,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
batch: {},
|
batch: {},
|
||||||
quickEntry: '',
|
quickEntry: '',
|
||||||
|
showingExecutionOptions: false,
|
||||||
|
executing: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -151,7 +177,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getRowRoute(row) {
|
getRowRoute(row) {
|
||||||
return `/ordering/rows/${row.uuid}/edit`
|
if (this.batch.mutable) {
|
||||||
|
return `/ordering/rows/${row.uuid}/edit`
|
||||||
|
}
|
||||||
|
return `/ordering/rows/${row.uuid}`
|
||||||
},
|
},
|
||||||
|
|
||||||
save(url) {
|
save(url) {
|
||||||
|
@ -251,6 +280,55 @@ export default {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
markOrderingIncomplete() {
|
||||||
|
this.$http.post(`/api/ordering-batch/${this.batch.uuid}/mark-incomplete`).then(response => {
|
||||||
|
if (response.data.error) {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Update failed: " + response.data.error,
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// update our batch, which should allow user to then modify it
|
||||||
|
this.batch = response.data.data
|
||||||
|
}
|
||||||
|
}, response => {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Update failed: (unknown error)",
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
executeBatch() {
|
||||||
|
let url = `/api/ordering-batch/${this.batch.uuid}/execute`
|
||||||
|
let params = {
|
||||||
|
// TODO: any reason to post params?
|
||||||
|
}
|
||||||
|
this.executing = true
|
||||||
|
this.$http.post(url, params).then(response => {
|
||||||
|
this.executing = false
|
||||||
|
if (response.data.error) {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Execute failed: " + response.data.error,
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// let user view the order, for confirmation
|
||||||
|
this.$router.push(`/ordering/${this.batch.uuid}`)
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Ordering batch has been executed",
|
||||||
|
type: 'is-success',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, response => {
|
||||||
|
this.executing = false
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Execute failed: (unknown error)",
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
api-object-url="/api/ordering-batch-row/"
|
api-object-url="/api/ordering-batch-row/"
|
||||||
model-path-prefix="/ordering"
|
model-path-prefix="/ordering"
|
||||||
row-path-prefix="/ordering/rows"
|
row-path-prefix="/ordering/rows"
|
||||||
@refresh="record => { row = record }"
|
@refresh="refresh"
|
||||||
is-row
|
is-row
|
||||||
@save="save">
|
@save="save"
|
||||||
|
:allow-edit="!row.batch_executed && !row.batch_complete"
|
||||||
|
:allow-delete="!row.batch_executed && !row.batch_complete"
|
||||||
|
quick-delete
|
||||||
|
@delete="deleteRow">
|
||||||
|
|
||||||
<b-field label="UPC">
|
<b-field label="UPC">
|
||||||
<span>
|
<span>
|
||||||
|
@ -42,7 +46,7 @@
|
||||||
ref="unitsOrdered"
|
ref="unitsOrdered"
|
||||||
@keypress.native="handleEnter">
|
@keypress.native="handleEnter">
|
||||||
</b-input>
|
</b-input>
|
||||||
<span v-if="mode == 'viewing'">
|
<span v-if="mode == 'viewing' || mode == 'deleting'">
|
||||||
{{ row.units_ordered_display }}
|
{{ row.units_ordered_display }}
|
||||||
</span>
|
</span>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
@ -89,11 +93,23 @@ export default {
|
||||||
if (this.mode == 'editing') {
|
if (this.mode == 'editing') {
|
||||||
this.$nextTick(function() {
|
this.$nextTick(function() {
|
||||||
this.$refs.casesOrdered.focus()
|
this.$refs.casesOrdered.focus()
|
||||||
|
// this.$refs.unitsOrdered.focus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
refresh(record) {
|
||||||
|
this.row = record
|
||||||
|
if (this.mode == 'editing' && !this.row.batch_mutable) {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Batch is not mutable.",
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
this.$router.push(`/ordering/rows/${this.row.uuid}`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
renderParentHeaderLabel(row) {
|
renderParentHeaderLabel(row) {
|
||||||
return row.batch_id_str
|
return row.batch_id_str
|
||||||
},
|
},
|
||||||
|
@ -118,8 +134,28 @@ export default {
|
||||||
url = `/api/ordering-batch-row/${this.row.uuid}`
|
url = `/api/ordering-batch-row/${this.row.uuid}`
|
||||||
}
|
}
|
||||||
this.$http.post(url, params).then(response => {
|
this.$http.post(url, params).then(response => {
|
||||||
|
if (response.data.error) {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: response.data.error || "Save failed: " + response.data.error,
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// go back to the purchase order
|
||||||
|
this.$router.push('/ordering/' + response.data.data.batch_uuid)
|
||||||
|
}
|
||||||
|
}, response => {
|
||||||
|
this.$buefy.toast.open({
|
||||||
|
message: "Save failed: (unknown error)",
|
||||||
|
type: 'is-danger',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteRow() {
|
||||||
|
let url = `/api/ordering-batch-row/${this.row.uuid}`
|
||||||
|
this.$http.delete(url).then(response => {
|
||||||
// go back to the purchase order
|
// go back to the purchase order
|
||||||
this.$router.push('/ordering/' + response.data.data.batch_uuid)
|
this.$router.push(`/ordering/${this.row.batch_uuid}`)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,26 @@
|
||||||
:api-index-sort="{field: 'id', dir: 'desc'}"
|
:api-index-sort="{field: 'id', dir: 'desc'}"
|
||||||
:api-index-filters="filters"
|
:api-index-filters="filters"
|
||||||
:label-renderer="renderLabel">
|
:label-renderer="renderLabel">
|
||||||
|
|
||||||
|
<b-field>
|
||||||
|
<b-radio-button v-model="selectedFilter"
|
||||||
|
native-value="pending">
|
||||||
|
<span>pending</span>
|
||||||
|
</b-radio-button>
|
||||||
|
<b-radio-button v-model="selectedFilter"
|
||||||
|
native-value="complete">
|
||||||
|
<span>complete</span>
|
||||||
|
</b-radio-button>
|
||||||
|
<b-radio-button v-model="selectedFilter"
|
||||||
|
native-value="executed">
|
||||||
|
<span>executed</span>
|
||||||
|
</b-radio-button>
|
||||||
|
<b-radio-button v-model="selectedFilter"
|
||||||
|
native-value="all">
|
||||||
|
<span>all</span>
|
||||||
|
</b-radio-button>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
</byjove-model-index>
|
</byjove-model-index>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -22,15 +42,31 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
filters: [
|
possibleFilters: {
|
||||||
{field: 'executed', op: 'is_null'},
|
'pending': [
|
||||||
{or: [
|
{field: 'executed', op: 'is_null'},
|
||||||
{field: 'complete', op: 'is_null'},
|
{or: [
|
||||||
{field: 'complete', op: 'eq', value: false},
|
{field: 'complete', op: 'is_null'},
|
||||||
]},
|
{field: 'complete', op: 'eq', value: false},
|
||||||
],
|
]},
|
||||||
|
],
|
||||||
|
'complete': [
|
||||||
|
{field: 'executed', op: 'is_null'},
|
||||||
|
{field: 'complete', op: 'eq', value: true},
|
||||||
|
],
|
||||||
|
'executed': [
|
||||||
|
{field: 'executed', op: 'is_not_null'},
|
||||||
|
],
|
||||||
|
'all': [],
|
||||||
|
},
|
||||||
|
selectedFilter: 'pending',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
filters: function() {
|
||||||
|
return this.possibleFilters[this.selectedFilter]
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
renderLabel(batch) {
|
renderLabel(batch) {
|
||||||
return `(${batch.id_str}) ${batch.vendor_display}`
|
return `(${batch.id_str}) ${batch.vendor_display}`
|
||||||
|
|
Loading…
Reference in a new issue