1
0
mirror of https://github.com/PanJiaChen/vue-element-admin.git synced 2025-08-10 20:39:48 +08:00

Point of Sale Processes (#583)

* Cancel sale transaction

* minimal change

* Copy Order

* Copy Line the Order

* add Traslation
This commit is contained in:
Elsio Sanchez 2021-02-11 11:55:45 -04:00 committed by GitHub
parent e2bbc598a7
commit 737d85b0ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 474 additions and 107 deletions

View File

@ -125,18 +125,20 @@ export function requestGetOrder(orderUuid) {
// Create order from POS
export function requestDeleteOrder({
posUuid,
customerUuid,
documentTypeUuid,
salesRepresentativeUuid
orderUuid
// posUuid,
// customerUuid,
// documentTypeUuid,
// salesRepresentativeUuid
}) {
return requestRest({
url: '/pos/delete-order',
data: {
pos_uuid: posUuid,
customer_uuid: customerUuid,
document_type_uuid: documentTypeUuid,
sales_representative_uuid: salesRepresentativeUuid
order_uuid: orderUuid
// pos_uuid: posUuid,
// customer_uuid: customerUuid,
// document_type_uuid: documentTypeUuid,
// sales_representative_uuid: salesRepresentativeUuid
}
})
.then(evaluateResponse)

View File

@ -10,26 +10,30 @@
close-on-click-modal
>
{{ modalMetadata.description }}<br><br>
<sequence-order
v-if="modalMetadata.isSortTab"
key="order"
:parent-uuid="parentUuid"
:container-uuid="modalMetadata.uuid"
:order="modalMetadata.sortOrderColumnName"
:included="modalMetadata.sortYesNoColumnName"
:identifiers-list="modalMetadata.identifierColumns"
:key-column="modalMetadata.keyColumn"
/>
<template v-else>
<main-panel
v-if="!isEmptyValue(modalMetadata.uuid)"
key="main-panel"
<div
v-if="panelType !== 'From'"
>
<sequence-order
v-if="modalMetadata.isSortTab"
key="order"
:parent-uuid="parentUuid"
:container-uuid="modalMetadata.uuid"
:metadata="modalMetadata"
:panel-type="modalMetadata.panelType"
:order="modalMetadata.sortOrderColumnName"
:included="modalMetadata.sortYesNoColumnName"
:identifiers-list="modalMetadata.identifierColumns"
:key-column="modalMetadata.keyColumn"
/>
</template>
<template v-else>
<main-panel
v-if="!isEmptyValue(modalMetadata.uuid)"
key="main-panel"
:parent-uuid="parentUuid"
:container-uuid="modalMetadata.uuid"
:metadata="modalMetadata"
:panel-type="modalMetadata.panelType"
/>
</template>
</div>
<span slot="footer" class="dialog-footer">
<el-button
@click="closeDialog"
@ -144,44 +148,59 @@ export default {
this.closeDialog()
} else if (action !== undefined) {
const fieldNotReady = this.$store.getters.isNotReadyForSubmit(action.uuid)
if (!fieldNotReady) {
this.closeDialog()
const porcesTabla = this.$store.getters.getProcessSelect.processTablaSelection
const selection = this.$store.getters.getProcessSelect
if (porcesTabla) {
// selection.forEach(element => {
this.$store.dispatch('selectionProcess', {
action: action, // process metadata
parentUuid: this.parentUuid,
containerUuid: this.containerUuid,
panelType: this.panelType, // determinate if get table name and record id (window) or selection (browser)
reportFormat: this.reportExportType,
recordUuidSelection: selection,
isProcessTableSelection: true,
routeToDelete: this.$route
})
// })
} else {
this.$store.dispatch('startProcess', {
action: action, // process metadata
parentUuid: this.parentUuid,
isProcessTableSelection: false,
containerUuid: this.containerUuid,
panelType: this.panelType, // determinate if get table name and record id (window) or selection (browser)
reportFormat: this.reportExportType,
routeToDelete: this.$route
})
.catch(error => {
console.warn(error)
})
}
} else {
this.showNotification({
type: 'warning',
title: this.$t('notifications.emptyValues'),
name: '<b>' + fieldNotReady.name + '.</b> ',
message: this.$t('notifications.fieldMandatory')
if (this.panelType === 'From') {
this.$store.dispatch('processPos', {
action: action, // process metadata
parentUuid: this.parentUuid,
idProcess: this.$store.getters.getFindOrder.id,
containerUuid: this.containerUuid,
panelType: this.panelType, // determinate if get table name and record id (window) or selection (browser)
parametersList: this.$store.getters.getPosParameters
})
.catch(error => {
console.warn(error)
})
this.closeDialog()
} else {
if (!fieldNotReady) {
this.closeDialog()
const porcesTabla = this.$store.getters.getProcessSelect.processTablaSelection
const selection = this.$store.getters.getProcessSelect
if (porcesTabla) {
// selection.forEach(element => {
this.$store.dispatch('selectionProcess', {
action: action, // process metadata
parentUuid: this.parentUuid,
containerUuid: this.containerUuid,
panelType: this.panelType, // determinate if get table name and record id (window) or selection (browser)
reportFormat: this.reportExportType,
recordUuidSelection: selection,
isProcessTableSelection: true,
routeToDelete: this.$route
})
// })
} else {
this.$store.dispatch('startProcess', {
action: action, // process metadata
parentUuid: this.parentUuid,
isProcessTableSelection: false,
containerUuid: this.containerUuid,
panelType: this.panelType, // determinate if get table name and record id (window) or selection (browser)
reportFormat: this.reportExportType,
routeToDelete: this.$route
})
.catch(error => {
console.warn(error)
})
}
} else {
this.showNotification({
type: 'warning',
title: this.$t('notifications.emptyValues'),
name: '<b>' + fieldNotReady.name + '.</b> ',
message: this.$t('notifications.fieldMandatory')
})
}
}
}
}

View File

@ -5,7 +5,11 @@
<br>
{{ $t('form.pos.optionsPoinSales.title') }}
</div>
<modal-dialog
:parent-uuid="processPos"
:container-uuid="processPos"
panel-type="From"
/>
<el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('form.pos.optionsPoinSales.salesOrder.title')" name="salesOrder">
<el-row :gutter="12" style="padding-right: 10px;">
@ -121,6 +125,30 @@
</p>
</el-card>
</el-col>
<el-col :span="size">
<el-card shadow="hover">
<p
:style="blockOption"
@click="copyLineOrder "
>
<i class="el-icon-document-copy" />
<br>
{{ $t('form.pos.optionsPoinSales.salesOrder.copyOrderLine') }}
</p>
</el-card>
</el-col>
<!-- <el-col :span="size">
<el-card shadow="hover">
<p
:style="blockOption"
@click="copyOrder "
>
<i class="el-icon-document-copy" />
<br>
{{ $t('form.pos.optionsPoinSales.salesOrder.copyOrder') }}
</p>
</el-card>
</el-col> -->
<el-col :span="size">
<el-card shadow="hover">
<p
@ -266,19 +294,26 @@ import {
requestPrintOrder,
requestGenerateImmediateInvoice,
requestCompletePreparedOrder,
requestReverseSalesTransaction,
// requestReverseSalesTransaction,
requestCreateWithdrawal,
requestCreateNewCustomerReturnOrder,
requestCashClosing,
requestDeleteOrder
} from '@/api/ADempiere/form/point-of-sales.js'
import ModalDialog from '@/components/ADempiere/Dialog'
import posProcess from '@/utils/ADempiere/constants/posProcess'
import orderLineMixin from '@/components/ADempiere/Form/VPOS/Order/orderLineMixin.js'
export default {
name: 'Options',
components: {
ListProductPrice,
OrdersList
OrdersList,
ModalDialog
},
mixins: [
orderLineMixin
],
props: {
metadata: {
type: Object,
@ -287,7 +322,8 @@ export default {
},
data() {
return {
activeName: ''
activeName: '',
processPos: ''
}
},
computed: {
@ -318,6 +354,9 @@ export default {
return this.$store.getters.getSellingPointsList
},
currentPOS() {
return this.$store.getters.getOrder
},
currentPoint() {
return this.$store.getters.getCurrentPOS
},
pointOfSalesId() {
@ -361,8 +400,7 @@ export default {
}).catch(error => {
console.info(`VPOS/Options component (New Order): ${error.message}`)
}).finally(() => {
const { templateBusinessPartner } = this.currentPOS
// const { templateBusinessPartner } = this.currentPOS
this.$store.commit('updateValuesOfContainer', {
containerUuid: this.metadata.containerUuid,
attributes: [{
@ -375,15 +413,15 @@ export default {
},
{
columnName: 'C_BPartner_ID',
value: templateBusinessPartner.id
value: 1000006
},
{
columnName: 'DisplayColumn_C_BPartner_ID',
value: templateBusinessPartner.name
value: 'Cliente Unico'
},
{
columnName: ' C_BPartner_ID_UUID',
value: templateBusinessPartner.uuid
value: '9f6cf428-9209-11e9-8046-0242ac140002'
}]
})
@ -417,9 +455,33 @@ export default {
})
},
reverseSalesTransaction() {
// TODO: Add BPartner
requestReverseSalesTransaction({
orderUuid: this.$route.query.action
const process = this.$store.getters.getProcess(posProcess[1].uuid)
this.$store.dispatch('startProcess', {
action: process,
isProcessTableSelection: false,
containerUuid: process.containerUuid,
parametersList: [
{
columnName: 'C_Order_ID',
value: this.currentPOS.id
},
{
columnName: 'Bill_BPartner_ID',
value: this.currentPOS.businessPartner.id
},
{
columnName: 'IsCancelled',
value: false
},
{
columnName: 'IsShipConfirm',
value: true
},
{
columnName: 'C_DocTypeRMA_ID',
value: 'VO'
}
]
})
},
createWithdrawal() {
@ -435,6 +497,25 @@ export default {
orderUuid: this.$route.query.action
})
},
showModal(action) {
this.$store.dispatch('setShowDialog', {
type: action.type,
action: {
...action,
containerUuid: action.uuid
}
})
},
copyOrder() {
this.processPos = posProcess[5].uuid
const process = this.$store.getters.getProcess(posProcess[5].uuid)
this.showModal(process)
},
copyLineOrder() {
this.processPos = posProcess[5].uuid
const process = this.$store.getters.getProcess(posProcess[5].uuid)
this.showModal(process)
},
cashClosing() {
const { uuid: posUuid, id: posId } = this.getCurrentPOS
requestCashClosing({
@ -446,7 +527,19 @@ export default {
requestDeleteOrder({
orderUuid: this.$route.query.action
})
this.newOrder()
.then(response => {
this.changePos(this.$store.getters.getCurrentPOS)
})
.finally(() => {
this.$store.dispatch('listOrdersFromServer', {
posUuid: this.$store.getters.getCurrentPOS.uuid
})
this.$message({
type: 'success',
message: 'Orden Cancelada',
showClose: true
})
})
}
}
}

View File

@ -50,6 +50,7 @@
<el-main style="padding-top: 0px; padding-right: 10px; padding-bottom: 0px; padding-left: 10px;">
<el-table
ref="linesTable"
v-loading="updateOrderProcessPos"
v-shortkey="shortsKey"
:data="allOrderLines"
border
@ -445,10 +446,10 @@ export default {
}
},
mounted() {
setTimeout(() => {
this.tenderTypeDisplaye()
this.currencyDisplaye()
}, 1500)
// setTimeout(() => {
// this.tenderTypeDisplaye()
// this.currencyDisplaye()
// }, 1500)
},
methods: {
changePos(posElement) {

View File

@ -45,7 +45,8 @@
:highlight-current-row="highlightRow"
:height="heightTable"
@shortkey.native="keyAction"
@current-change="handleCurrentChange"
@current-change="orderPrpcess"
@row-dblclick="handleCurrentChange"
>
<el-table-column
prop="documentNo"
@ -197,11 +198,18 @@ export default {
// },
created() {
this.unsubscribe = this.subscribeChanges()
if (this.isReadyFromGetData) {
this.loadOrdersList()
}
},
mounted() {
const listOrder = this.$store.getters.getListOrderLine
if (this.isEmptyValue(listOrder)) {
this.$store.dispatch('listOrdersFromServer', {
posUuid: this.$store.getters.getCurrentPOS.uuid
})
}
},
beforeDestroy() {
this.unsubscribe()
},
@ -315,6 +323,13 @@ export default {
})
return valuesToSend
},
orderPrpcess(row) {
const parametersList = [{
columnName: 'C_Order_ID',
value: row.id
}]
this.$store.dispatch('addParametersProcessPos', parametersList)
}
}
}

View File

@ -10,6 +10,7 @@ import {
formatPrice,
formatQuantity
} from '@/utils/ADempiere/valueFormat.js'
import posProcess from '@/utils/ADempiere/constants/posProcess'
export default {
name: 'POSMixin',
@ -51,7 +52,8 @@ export default {
quantityAvailable: 0
},
edit: false,
displayType: ''
displayType: '',
process: posProcess
}
},
computed: {
@ -80,7 +82,18 @@ export default {
}
}
return this.$store.getters.getFindOrder
return {
documentType: {},
documentStatus: {
value: ''
},
totalLines: 0,
grandTotal: 0,
salesRepresentative: {},
businessPartner: {
value: ''
}
}
},
currentPoint() {
return this.$store.getters.getCurrentPOS
@ -103,6 +116,9 @@ export default {
return currentPOS.templateBusinessPartner
}
return false
},
updateOrderProcessPos() {
return this.$store.getters.getUpdateOrderPos
}
},
watch: {
@ -129,6 +145,12 @@ export default {
if (bPartnerToSet) {
this.setBusinessPartner(bPartnerToSet)
}
},
updateOrderProcessPos(value) {
if (value) {
this.reloadOrder(true)
this.$store.dispatch('updateOrderPos', false)
}
}
},
created() {
@ -141,12 +163,17 @@ export default {
this.listOrderLines(this.currentOrder)
}
}
this.findProcess(this.process)
this.unsubscribe = this.subscribeChanges()
},
beforeDestroy() {
this.unsubscribe()
},
mounted() {
if (this.isEmptyValue(this.currentOrder)) {
this.reloadOrder(true, this.$route.query.action)
}
},
methods: {
formatDate,
formatPrice,
@ -295,7 +322,6 @@ export default {
// user session
const salesRepresentativeUuid = this.$store.getters['user/getUserUuid']
requestCreateOrder({
posUuid,
customerUuid,
@ -342,12 +368,11 @@ export default {
orderUuid = this.$store.getters.getOrder.uuid // this.currentOrder.uuid
}
}
if (!this.isEmptyValue(orderUuid)) {
requestGetOrder(orderUuid)
.then(orderResponse => {
this.fillOrder(orderResponse)
this.$store.dispatch('currentOrder', orderResponse)
this.fillOrder(orderResponse)
this.listOrderLines(orderResponse)
})
.catch(error => {
@ -449,7 +474,6 @@ export default {
this.$refs.linesTable.setCurrentRow(this.listOrderLine[0])
},
shortcutKeyMethod(event) {
console.log(event.srcKey)
switch (event.srcKey) {
// case 'options':
case 'up':
@ -499,6 +523,11 @@ export default {
})
break
}
},
findProcess(processPos) {
processPos.forEach(item => {
this.$store.dispatch('getProcessFromServer', { containerUuid: item.uuid })
})
}
}
}

View File

@ -346,7 +346,9 @@ export default {
cancelSaleTransaction: 'Cancel Sale Transaction',
createPos: 'Create Point of Sale Withdrawal',
print: 'Print Document',
cancelOrder: 'Cancel Order'
cancelOrder: 'Cancel Order',
copyOrderLine: 'Copy Order Lines',
copyOrder: 'Copy Order'
},
cashManagement: {
title: 'Cash Management',

View File

@ -321,7 +321,9 @@ export default {
cancelSaleTransaction: 'Anular Transacción de Venta',
createPos: 'Crear Retiro de Punto de Venta',
print: 'Imprimir Documento',
cancelOrder: 'Cancelar Orden'
cancelOrder: 'Cancelar Orden',
copyOrderLine: 'Copiar Lineas de la Orden',
copyOrder: 'Copiar Orden'
},
cashManagement: {
title: 'Gestión de Caja',

View File

@ -294,11 +294,6 @@ const collection = {
})
.catch(error => {
console.warn(`ListPaymentsFromServer: ${error.message}. Code: ${error.code}.`)
showMessage({
type: 'error',
message: error.message,
showClose: true
})
})
},
tenderTypeDisplaye({ commit }, tenderType) {

View File

@ -10,6 +10,7 @@ const withoutResponse = {
isLoaded: false,
isReload: true,
recordCount: 0,
currentPOS: {},
nextPageToken: undefined
}
@ -58,7 +59,6 @@ const pointOfSales = {
...response,
userUuid
})
const posList = response.sellingPointsList
const getterPos = getters.getPointOfSalesUuid
let pos
@ -138,14 +138,21 @@ const pointOfSales = {
// current pos info
getCurrentPOS: (state, getters) => {
const userUuid = getters['user/getUserUuid']
const sellingPointsList = state.pointOfSales.sellingPointsList.length
if (sellingPointsList > 1) {
return state.pointOfSales.sellingPointsList.find(elem => elem.salesRepresentative.uuid === userUuid)
let currentPOS
const sellingPointsList = state.pointOfSales.sellingPointsList
if (!isEmptyValue(sellingPointsList) && (sellingPointsList.length > 1)) {
currentPOS = state.pointOfSales.sellingPointsList.find(elem => elem.salesRepresentative.uuid === userUuid)
}
if (isEmptyValue(state.pointOfSales)) {
return undefined
if (!isEmptyValue(currentPOS)) {
return currentPOS
}
return state.pointOfSales.currentPOS
if (isEmptyValue(state.pointOfSales.currentPOS) && (!isEmptyValue(sellingPointsList))) {
return state.pointOfSales.sellingPointsList[0]
}
if (state.pointOfSales.currentPOS) {
return state.pointOfSales.currentPOS
}
return undefined
},
getSellingPointsList: (state, getters) => {
return getters.getPointOfSales.sellingPointsList

View File

@ -124,8 +124,8 @@ const ordes = {
setOrder({ commit }, order) {
commit('setOrder', order)
},
currentOrder({ commit }, current) {
commit('findOrder', current)
currentOrder({ commit }, findOrder) {
commit('findOrder', findOrder)
},
findOrderServer({ commit }, orderUuid) {
if (typeof orderUuid === 'string' && !isEmptyValue(orderUuid)) {

View File

@ -147,7 +147,7 @@ export default {
processResult = {
...processResult,
menuParentUuid,
processIdPath: routeToDelete.path,
processIdPath: isEmptyValue(routeToDelete) ? '' : routeToDelete.path,
printFormatUuid: action.printFormatUuid,
// process attributes
action: processDefinition.name,
@ -1137,5 +1137,153 @@ export default {
if (!isEmptyValue(reportFormat)) {
commit('changeFormatReport', reportFormat)
}
},
/**
* Ejecutar Procesos del POS
*/
processPos({ commit, state, dispatch, getters, rootGetters }, {
parentUuid,
containerUuid,
panelType,
action,
parametersList,
idProcess,
isActionDocument,
menuParentUuid,
routeToDelete
}) {
return new Promise((resolve, reject) => {
const processDefinition = !isEmptyValue(isActionDocument) ? action : rootGetters.getProcess(action.uuid)
if (isEmptyValue(parametersList)) {
parametersList = rootGetters.getParametersToServer({
containerUuid: processDefinition.uuid
})
}
const isSession = !isEmptyValue(getToken())
let procesingMessage = {
close: () => false
}
if (isSession) {
procesingMessage = showNotification({
title: language.t('notifications.processing'),
message: processDefinition.name,
summary: processDefinition.description,
type: 'info'
})
}
const timeInitialized = (new Date()).getTime()
let processResult = {
// panel attributes from where it was executed
parentUuid,
containerUuid,
panelType,
lastRun: timeInitialized,
parametersList,
logs: [],
isError: false,
isProcessing: true,
summary: '',
resultTableName: '',
output: {
uuid: '',
name: '',
description: '',
fileName: '',
output: '',
outputStream: '',
reportType: ''
}
}
if (!isEmptyValue(isActionDocument)) {
processResult = {
...processResult,
processUuid: action.uuid,
processId: action.id,
processName: 'Procesar Orden',
parameters: parametersList
}
} else {
// Run process on server and wait for it for notify
// uuid of process
processResult = {
...processResult,
menuParentUuid,
processIdPath: isEmptyValue(routeToDelete) ? '' : routeToDelete.path,
printFormatUuid: action.printFormatUuid,
// process attributes
action: processDefinition.name,
name: processDefinition.name,
description: processDefinition.description,
instanceUuid: '',
processUuid: processDefinition.uuid,
processId: processDefinition.id,
processName: processDefinition.processName,
parameters: parametersList,
isReport: processDefinition.isReport
}
}
commit('addInExecution', processResult)
requestRunProcess({
uuid: processDefinition.uuid,
recordId: idProcess,
parametersList
})
.then(runProcessResponse => {
const { output } = runProcessResponse
let logList = []
if (!isEmptyValue(runProcessResponse.logsList)) {
logList = runProcessResponse.logsList
}
const link = {
href: undefined,
download: undefined
}
// assign new attributes
Object.assign(processResult, {
...runProcessResponse,
url: link.href,
download: link.download,
logs: logList,
output
})
resolve(processResult)
if (!isEmptyValue(processResult.output)) {
dispatch('setReportTypeToShareLink', processResult.output.reportType)
}
})
.catch(error => {
Object.assign(processResult, {
isError: true,
message: error.message,
isProcessing: false
})
console.warn(`Error running the process ${error.message}. Code: ${error.code}.`)
reject(error)
})
.finally(() => {
commit('addNotificationProcess', processResult)
dispatch('finishProcess', {
processOutput: processResult,
procesingMessage,
routeToDelete
})
commit('deleteInExecution', {
containerUuid
})
dispatch('setProcessTable', {
valueRecord: 0,
tableName: '',
processTable: false
})
dispatch('setProcessSelect', {
finish: true
})
dispatch('updateOrderPos', true)
})
})
}
}

View File

@ -26,7 +26,9 @@ const initStateUtils = {
isLoaded: false
},
splitWidthRight: 3,
splitWidthLeft: 3
splitWidthLeft: 3,
parametersProcessPos: [],
updateOrder: false
}
export default {
@ -89,6 +91,12 @@ export default {
},
setSplitWidthLeft(state, splitWidthLeft) {
state.splitWidthLeft = splitWidthLeft
},
parametersProcessPos(state, params) {
state.parametersProcessPos = params
},
setUpdateOrder(state, order) {
state.updateOrder = order
}
},
actions: {
@ -146,6 +154,12 @@ export default {
},
changeWidthLeft({ commit }, newWidthLeft) {
commit('setSplitWidthLeft', newWidthLeft)
},
addParametersProcessPos({ commit }, params) {
commit('parametersProcessPos', params)
},
updateOrderPos({ commit }, params) {
commit('setUpdateOrder', params)
}
},
getters: {
@ -209,6 +223,12 @@ export default {
},
getWidthLeft: (state) => {
return state.splitWidthLeft
},
getPosParameters: (state) => {
return state.parametersProcessPos
},
getUpdateOrderPos: (state) => {
return state.updateOrder
}
}
}

View File

@ -0,0 +1,27 @@
const posProcess = [
{
name: 'C_POS Generate Immediate Invoice',
uuid: 'a42cce58-fb40-11e8-a479-7a0060f0aa01'
},
{
name: 'C_POS ReverseTheSalesTransaction',
uuid: 'a42ccebc-fb40-11e8-a479-7a0060f0aa01'
},
{
name: 'C_POS CreateOrderBasedOnAnother',
uuid: 'a42ccc46-fb40-11e8-a479-7a0060f0aa01'
},
{
name: 'C_POS Withdrawal',
uuid: 'a42ce0a0-fb40-11e8-a479-7a0060f0aa01'
},
{
name: 'C_POS Bank Statement Close',
uuid: 'a42ce118-fb40-11e8-a479-7a0060f0aa01'
},
{
name: 'C_Order CopyFrom',
uuid: 'a42ad0c6-fb40-11e8-a479-7a0060f0aa01'
}
]
export default posProcess

View File

@ -9,6 +9,11 @@
v-if="showContextMenu"
style="height: 39px; background: white;"
>
<modal-dialog
:parent-uuid="$route.meta.parentUuid"
:container-uuid="formUuid"
:panel-type="panelType"
/>
<context-menu
:menu-parent-uuid="$route.meta.parentUuid"
:container-uuid="formUuid"
@ -83,12 +88,14 @@
<script>
import ContextMenu from '@/components/ADempiere/ContextMenu'
import FormPanel from '@/components/ADempiere/Form'
import ModalDialog from '@/components/ADempiere/Dialog'
export default {
name: 'FormView',
components: {
ContextMenu,
FormPanel
FormPanel,
ModalDialog
},
data() {
return {