Browse Source

新品流程OK

master
常熟吴彦祖 2 weeks ago
parent
commit
bf230c78bf
  1. 651
      src/views/modules/order/poOrder.vue
  2. 10
      src/views/modules/srmSupplier/supplierList.vue

651
src/views/modules/order/poOrder.vue

@ -295,21 +295,21 @@
:advanced-query-data="advancedQueryData" :advanced-query-data="advancedQueryData"
@query="handleSearch" /> @query="handleSearch" />
<!-- 新增 PO 订单 -->
<el-dialog title="新增 PO 订单" :visible.sync="addDialogVisible" width="1000px" top="4vh"
<!-- 新增 PO 订单主记录 + 明细暂存 -->
<el-dialog title="新增 PO 订单" :visible.sync="addDialogVisible" width="1180px" top="4vh"
:close-on-click-modal="false" append-to-body> :close-on-click-modal="false" append-to-body>
<div class="po-add-form-wrap"> <div class="po-add-form-wrap">
<el-form ref="addFormRef" :model="addForm" label-position="top" size="small">
<el-form ref="addMasterFormRef" :model="addForm" label-position="top" size="small">
<el-row :gutter="15"> <el-row :gutter="15">
<el-col v-for="field in addBaseFields" :key="field.fieldCode" :span="getAddFieldSpan(field)">
<el-col v-for="field in addMasterBaseFields" :key="`master-${field.fieldCode}`" :span="getAddFieldSpan(field)">
<el-form-item :label="field.fieldLabel" :required="field.requiredFlag === 'Y'"> <el-form-item :label="field.fieldLabel" :required="field.requiredFlag === 'Y'">
<template v-if="isAddChooserField(field)"> <template v-if="isAddChooserField(field)">
<el-input <el-input
v-model="addForm[getAddFieldProp(field)]" v-model="addForm[getAddFieldProp(field)]"
readonly readonly
:placeholder="getAddChooserPlaceholder(field)" :placeholder="getAddChooserPlaceholder(field)"
@click.native="openAddChooserByField(field)">
<i slot="suffix" class="el-icon-search" style="cursor:pointer" @click.stop="openAddChooserByField(field)"></i>
@click.native="openAddChooserByField(field, 'master')">
<i slot="suffix" class="el-icon-search" style="cursor:pointer" @click.stop="openAddChooserByField(field, 'master')"></i>
</el-input> </el-input>
</template> </template>
<template v-else-if="isAddSelectField(field)"> <template v-else-if="isAddSelectField(field)">
@ -346,19 +346,119 @@
v-model="addForm[getAddFieldProp(field)]" v-model="addForm[getAddFieldProp(field)]"
:type="isAddNumberField(field) ? 'number' : 'text'" :type="isAddNumberField(field) ? 'number' : 'text'"
:disabled="isAddFieldDisabled(field)" :disabled="isAddFieldDisabled(field)"
@input="onAddFieldInput(field)" />
@input="onAddFieldInput(field, 'master')" />
</template> </template>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row v-if="addExtFields.length" :gutter="24">
<el-col v-for="field in addExtFields" :key="field.fieldCode" :span="6">
</el-form>
<div class="po-add-detail-toolbar">
<span class="po-add-detail-title">明细暂存列表</span>
<div>
<el-button type="primary" size="mini" @click="openAddDetailDialog">新增</el-button>
<el-button size="mini" :disabled="!hasSelectedAddDetailRow" @click="openEditAddDetailDialog">修改</el-button>
<el-button size="mini" :disabled="!hasSelectedAddDetailRow" @click="removeAddDetailRow">删除</el-button>
<el-button size="mini" :disabled="!hasSelectedAddDetailRow" @click="openCopyAddDetailDialog">复制</el-button>
</div>
</div>
<el-table
ref="addDetailTable"
:data="addDetailRows"
:height="320"
border
stripe
highlight-current-row
empty-text="请点击新增维护明细"
@current-change="onAddDetailCurrentChange"
@row-click="onAddDetailRowClick">
<el-table-column type="index" label="#" width="50" header-align="center" align="center" />
<el-table-column prop="partNo" :label="getAddTableColumnLabel('part_no', '产品编码')" min-width="150" header-align="center" align="center" />
<el-table-column prop="item" :label="getAddTableColumnLabel('item', 'Item')" min-width="120" header-align="center" align="center" />
<el-table-column prop="sku" :label="getAddTableColumnLabel('sku', 'SKU')" min-width="120" header-align="center" align="center" />
<el-table-column prop="qty" :label="getAddTableColumnLabel('qty', 'PO Qty')" min-width="110" header-align="center" align="right" />
<el-table-column prop="price" :label="getAddTableColumnLabel('price', 'Unit Price')" min-width="120" header-align="center" align="right" />
<el-table-column prop="value" :label="getAddTableColumnLabel('value', 'PO Value')" min-width="120" header-align="center" align="right" />
<el-table-column prop="wantReceiveDate" :label="getAddTableColumnLabel('want_receive_date', 'Promise Date')" min-width="130" header-align="center" align="center" />
<el-table-column prop="remark" :label="getAddTableColumnLabel('remark', 'Comments')" min-width="220" header-align="center" align="left" show-overflow-tooltip />
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="addFormSaving" @click="saveAddPoOrder">保存</el-button>
<el-button @click="addDialogVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 新增明细弹窗 -->
<el-dialog
:title="addDetailDialogTitle"
:visible.sync="addDetailDialogVisible"
width="1000px"
top="6vh"
append-to-body
:close-on-click-modal="false">
<div class="po-add-form-wrap">
<el-form ref="addDetailFormRef" :model="addDetailForm" label-position="top" size="small">
<el-row :gutter="15">
<el-col v-for="field in addDetailBaseFields" :key="`detail-${field.fieldCode}`" :span="getAddFieldSpan(field)">
<el-form-item :label="field.fieldLabel" :required="field.requiredFlag === 'Y'">
<template v-if="isAddChooserField(field)">
<el-input
v-model="addDetailForm[getAddFieldProp(field)]"
readonly
:placeholder="getAddChooserPlaceholder(field)"
@click.native="openAddChooserByField(field, 'detail')">
<i slot="suffix" class="el-icon-search" style="cursor:pointer" @click.stop="openAddChooserByField(field, 'detail')"></i>
</el-input>
</template>
<template v-else-if="isAddSelectField(field)">
<el-select
v-model="addDetailForm[getAddFieldProp(field)]"
:filterable="isAddFilterableSelectField(field)"
clearable
style="width:100%"
:disabled="isAddFieldDisabled(field)">
<el-option
v-for="opt in getAddFieldSelectOptions(field)"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</template>
<template v-else-if="isAddDateField(field)">
<el-date-picker
v-model="addDetailForm[getAddFieldProp(field)]"
type="date"
value-format="yyyy-MM-dd"
style="width:100%"
:disabled="isAddFieldDisabled(field)" />
</template>
<template v-else-if="isAddTextareaField(field)">
<el-input
v-model="addDetailForm[getAddFieldProp(field)]"
type="textarea"
:rows="2"
:disabled="isAddFieldDisabled(field)" />
</template>
<template v-else>
<el-input
v-model="addDetailForm[getAddFieldProp(field)]"
:type="isAddNumberField(field) ? 'number' : 'text'"
:disabled="isAddFieldDisabled(field)"
@input="onAddFieldInput(field, 'detail')" />
</template>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="addDetailExtFields.length" :gutter="24">
<el-col v-for="field in addDetailExtFields" :key="`detail-ext-${field.fieldCode}`" :span="6">
<el-form-item :label="field.fieldLabel" :required="field.requiredFlag === 'Y'"> <el-form-item :label="field.fieldLabel" :required="field.requiredFlag === 'Y'">
<com-po-order-dynamic-field-renderer <com-po-order-dynamic-field-renderer
:field="field" :field="field"
:site="searchData.site" :site="searchData.site"
:value="getAddExtValue(field.fieldCode)"
@input="val => setAddExtValue(field.fieldCode, val)"
:value="getAddDetailExtValue(field.fieldCode)"
@input="val => setAddDetailExtValue(field.fieldCode, val)"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -366,8 +466,8 @@
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="addFormSaving" @click="saveAddPoOrder"></el-button>
<el-button @click="addDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveAddDetailDraft"></el-button>
<el-button @click="addDetailDialogVisible = false">取消</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -464,7 +564,8 @@ const ADD_TEXTAREA_FIELD_CODES = new Set(['remark'])
const ADD_FULL_ROW_FIELD_CODES = new Set(['remark']) const ADD_FULL_ROW_FIELD_CODES = new Set(['remark'])
const ADD_NUMBER_FIELD_CODES = new Set(['price', 'qty', 'ship_qty', 'sum_price']) const ADD_NUMBER_FIELD_CODES = new Set(['price', 'qty', 'ship_qty', 'sum_price'])
const ADD_FILTERABLE_SELECT_FIELD_CODES = new Set(['customer', 'buyer']) const ADD_FILTERABLE_SELECT_FIELD_CODES = new Set(['customer', 'buyer'])
const ADD_READONLY_DEFAULT_TODAY_FIELD_CODES = new Set(['order_date', 'create_date'])
const ADD_FORCE_DETAIL_FIELD_CODES = new Set(['part_no', 'price', 'qty'])
const ADD_READONLY_DEFAULT_TODAY_FIELD_CODES = new Set(['create_date'])
const ADD_EDITABLE_DEFAULT_TODAY_FIELD_CODES = new Set(['po_place_date']) const ADD_EDITABLE_DEFAULT_TODAY_FIELD_CODES = new Set(['po_place_date'])
const ADD_SELECT_OPTIONS_FIELD_CODE_MAP = { const ADD_SELECT_OPTIONS_FIELD_CODE_MAP = {
order_type: 'poOrderTypeOptions', order_type: 'poOrderTypeOptions',
@ -531,6 +632,13 @@ export default {
eamTagNo: '', eamTagNo: '',
eamPickField: '', eamPickField: '',
addForm: {}, addForm: {},
addDetailDialogVisible: false,
addDetailDialogMode: 'create',
addDetailForm: {},
addDetailRows: [],
addDetailCurrentDraftId: '',
addDetailEditingDraftId: '',
addDetailDraftSeq: 0,
supplierPartDialogVisible: false, supplierPartDialogVisible: false,
supplierPartDialogLoading: false, supplierPartDialogLoading: false,
supplierPartDialogRows: [], supplierPartDialogRows: [],
@ -1594,6 +1702,9 @@ export default {
addExtFields () { addExtFields () {
return getEditableExtFieldsFromSchema(this.addFormSchemaFields) return getEditableExtFieldsFromSchema(this.addFormSchemaFields)
}, },
addDetailExtFields () {
return this.addExtFields
},
addBaseFields () { addBaseFields () {
if (!Array.isArray(this.addFormSchemaFields)) { if (!Array.isArray(this.addFormSchemaFields)) {
return [] return []
@ -1619,6 +1730,27 @@ export default {
}) })
return [...normalFields, ...tailFields] return [...normalFields, ...tailFields]
}, },
addMasterBaseFields () {
return this.addBaseFields.filter(field => this.isAddMasterField(field))
},
addDetailBaseFields () {
return this.addBaseFields.filter(field => !this.isAddMasterField(field))
},
hasSelectedAddDetailRow () {
if (!this.addDetailCurrentDraftId) {
return false
}
return this.addDetailRows.some(row => row && row._draftId === this.addDetailCurrentDraftId)
},
addDetailDialogTitle () {
if (this.addDetailDialogMode === 'edit') {
return '修改明细'
}
if (this.addDetailDialogMode === 'copy') {
return '复制明细'
}
return '新增明细'
},
uploadColumnMappingEntries () { uploadColumnMappingEntries () {
if (!this.uploadColumnMapping || typeof this.uploadColumnMapping !== 'object') { if (!this.uploadColumnMapping || typeof this.uploadColumnMapping !== 'object') {
return [] return []
@ -1761,6 +1893,42 @@ export default {
const code = this.getAddFieldCode(field) const code = this.getAddFieldCode(field)
return code.indexOf('ext_') === 0 return code.indexOf('ext_') === 0
}, },
normalizeAddFieldLabel (field) {
return String((field && field.fieldLabel) || '').trim().toLowerCase().replace(/\s+/g, ' ')
},
isAddCreateDateField (field) {
const code = this.getAddFieldCode(field)
if (ADD_READONLY_DEFAULT_TODAY_FIELD_CODES.has(code)) {
return true
}
return this.normalizeAddFieldLabel(field) === 'create date'
},
isAddPoPlaceDateField (field) {
const code = this.getAddFieldCode(field)
if (ADD_EDITABLE_DEFAULT_TODAY_FIELD_CODES.has(code)) {
return true
}
return this.normalizeAddFieldLabel(field) === 'po place date'
},
isAddMasterField (field) {
const code = this.getAddFieldCode(field)
if (ADD_FORCE_DETAIL_FIELD_CODES.has(code)) {
return false
}
const mandatoryFlag = String((field && field.mandatoryFlag) || '').trim().toUpperCase()
return mandatoryFlag === 'Y'
},
getSchemaFieldByCode (fieldCode) {
const normalizedCode = String(fieldCode || '').trim().toLowerCase()
if (!normalizedCode || !Array.isArray(this.addFormSchemaFields)) {
return null
}
return this.addFormSchemaFields.find(field => this.getAddFieldCode(field) === normalizedCode) || null
},
getAddTableColumnLabel (fieldCode, fallback) {
const field = this.getSchemaFieldByCode(fieldCode)
return (field && field.fieldLabel) || fallback || fieldCode
},
snakeToCamel (text) { snakeToCamel (text) {
return String(text || '').replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase()) return String(text || '').replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase())
}, },
@ -1770,18 +1938,18 @@ export default {
isAddChooserField (field) { isAddChooserField (field) {
return ADD_CHOOSER_FIELD_CODES.has(this.getAddFieldCode(field)) return ADD_CHOOSER_FIELD_CODES.has(this.getAddFieldCode(field))
}, },
openAddChooserByField (field) {
openAddChooserByField (field, target = 'master') {
const code = this.getAddFieldCode(field) const code = this.getAddFieldCode(field)
if (code === 'supplier_name') { if (code === 'supplier_name') {
this.openAddSupplierSelect()
this.openAddSupplierSelect(target)
} else if (code === 'part_no') { } else if (code === 'part_no') {
this.openAddPartNoSelect()
this.openAddPartNoSelect(target)
} else if (code === 'departure') { } else if (code === 'departure') {
this.openAddDepartureSelect()
this.openAddDepartureSelect(target)
} else if (code === 'destination') { } else if (code === 'destination') {
this.openAddDestinationSelect()
this.openAddDestinationSelect(target)
} else if (code === 'ship_via') { } else if (code === 'ship_via') {
this.openAddShipViaSelect()
this.openAddShipViaSelect(target)
} }
}, },
getAddChooserPlaceholder (field) { getAddChooserPlaceholder (field) {
@ -1834,7 +2002,7 @@ export default {
if (code === 'customer') { if (code === 'customer') {
return true return true
} }
if (ADD_READONLY_DEFAULT_TODAY_FIELD_CODES.has(code)) {
if (this.isAddCreateDateField(field)) {
return true return true
} }
if (ADD_DISPLAY_ONLY_FIELD_CODES.has(code)) { if (ADD_DISPLAY_ONLY_FIELD_CODES.has(code)) {
@ -1849,33 +2017,50 @@ export default {
} }
return this.isAddTextareaField(field) ? 12 : 6 return this.isAddTextareaField(field) ? 12 : 6
}, },
onAddFieldInput (field) {
onAddFieldInput (field, target = 'master') {
const code = this.getAddFieldCode(field) const code = this.getAddFieldCode(field)
if (code === 'price' || code === 'qty') { if (code === 'price' || code === 'qty') {
this.recalcAddFormValue()
this.recalcAddFormValue(target)
} }
if (code === 'qty') { if (code === 'qty') {
this.scheduleAutoFillAddPriceByTierPrice()
this.scheduleAutoFillAddPriceByTierPrice(target)
} }
}, },
scheduleAutoFillAddPriceByTierPrice () {
getAddTargetForm (target = 'master') {
return target === 'detail' ? this.addDetailForm : this.addForm
},
getSupplierCodeForTargetForm (form, target = 'master') {
const formSupplier = String((form && form.supplierNo) || '').trim()
if (formSupplier) {
return formSupplier
}
if (target === 'detail') {
return String((this.addForm && this.addForm.supplierNo) || '').trim()
}
return ''
},
scheduleAutoFillAddPriceByTierPrice (target = 'master') {
if (this.addPriceLookupTimer) { if (this.addPriceLookupTimer) {
clearTimeout(this.addPriceLookupTimer) clearTimeout(this.addPriceLookupTimer)
this.addPriceLookupTimer = null this.addPriceLookupTimer = null
} }
this.addPriceLookupTimer = setTimeout(() => { this.addPriceLookupTimer = setTimeout(() => {
this.addPriceLookupTimer = null this.addPriceLookupTimer = null
this.autoFillAddPriceByTierPrice()
this.autoFillAddPriceByTierPrice(target)
}, 250) }, 250)
}, },
autoFillAddPriceByTierPrice () {
autoFillAddPriceByTierPrice (target = 'master') {
if (!this.addDialogVisible) { if (!this.addDialogVisible) {
return Promise.resolve() return Promise.resolve()
} }
const targetForm = this.getAddTargetForm(target)
if (!targetForm) {
return Promise.resolve()
}
const site = (this.searchData.site || this.$store.state.user.site || '').trim() const site = (this.searchData.site || this.$store.state.user.site || '').trim()
const supplierCode = String(this.addForm.supplierNo || '').trim()
const partNo = String(this.addForm.partNo || '').trim()
const qtyVal = this.addForm.qty
const supplierCode = this.getSupplierCodeForTargetForm(targetForm, target)
const partNo = String(targetForm.partNo || '').trim()
const qtyVal = targetForm.qty
if (!site || !supplierCode || !partNo || qtyVal === '' || qtyVal === null || qtyVal === undefined) { if (!site || !supplierCode || !partNo || qtyVal === '' || qtyVal === null || qtyVal === undefined) {
return Promise.resolve() return Promise.resolve()
} }
@ -1903,8 +2088,8 @@ export default {
if (normalizedPrice === '') { if (normalizedPrice === '') {
return return
} }
this.$set(this.addForm, 'price', normalizedPrice)
this.recalcAddFormValue()
this.$set(targetForm, 'price', normalizedPrice)
this.recalcAddFormValue(target)
}).catch(() => {}) }).catch(() => {})
}, },
findCurrentTierPriceByQty (rows, qty) { findCurrentTierPriceByQty (rows, qty) {
@ -2253,7 +2438,11 @@ export default {
const { supplierNo, supplierName } = parseSupplierChooselistRow(data) const { supplierNo, supplierName } = parseSupplierChooselistRow(data)
if (ctx === 'add') { if (ctx === 'add') {
this.fillSupplierShortFields(this.addForm, supplierNo, supplierName, false).then(() => { this.fillSupplierShortFields(this.addForm, supplierNo, supplierName, false).then(() => {
this.scheduleAutoFillAddPriceByTierPrice()
this.scheduleAutoFillAddPriceByTierPrice('master')
})
} else if (ctx === 'addDetail') {
this.fillSupplierShortFields(this.addDetailForm, supplierNo, supplierName, false).then(() => {
this.scheduleAutoFillAddPriceByTierPrice('detail')
}) })
} else if (this.currentSelectRow) { } else if (this.currentSelectRow) {
const row = this.currentSelectRow const row = this.currentSelectRow
@ -2268,7 +2457,11 @@ export default {
if (ctx === 'add') { if (ctx === 'add') {
this.$set(this.addForm, 'partNo', partNo) this.$set(this.addForm, 'partNo', partNo)
this.fillPartCategorySku(partNo, this.addForm) this.fillPartCategorySku(partNo, this.addForm)
this.scheduleAutoFillAddPriceByTierPrice()
this.scheduleAutoFillAddPriceByTierPrice('master')
} else if (ctx === 'addDetail') {
this.$set(this.addDetailForm, 'partNo', partNo)
this.fillPartCategorySku(partNo, this.addDetailForm)
this.scheduleAutoFillAddPriceByTierPrice('detail')
} else if (this.currentPartNoRow) { } else if (this.currentPartNoRow) {
this.$set(this.currentPartNoRow, 'partNo', partNo) this.$set(this.currentPartNoRow, 'partNo', partNo)
this.fillPartCategorySku(partNo, this.currentPartNoRow) this.fillPartCategorySku(partNo, this.currentPartNoRow)
@ -2289,6 +2482,12 @@ export default {
} else if (this.eamPickField === 'destination') { } else if (this.eamPickField === 'destination') {
this.addForm.destination = code this.addForm.destination = code
} }
} else if (ctx === 'addDetail') {
if (this.eamPickField === 'departure') {
this.addDetailForm.departure = code
} else if (this.eamPickField === 'destination') {
this.addDetailForm.destination = code
}
} else if (this.eamPickField === 'departure' && this.currentDepartureRow) { } else if (this.eamPickField === 'departure' && this.currentDepartureRow) {
this.$set(this.currentDepartureRow, 'departure', code) this.$set(this.currentDepartureRow, 'departure', code)
this.$set(this.currentDepartureRow, 'departureName', portName) this.$set(this.currentDepartureRow, 'departureName', portName)
@ -2306,6 +2505,8 @@ export default {
const via = data.method_desc || data.methodDesc || data.shipVia || '' const via = data.method_desc || data.methodDesc || data.shipVia || ''
if (ctx === 'add') { if (ctx === 'add') {
this.addForm.shipVia = via this.addForm.shipVia = via
} else if (ctx === 'addDetail') {
this.addDetailForm.shipVia = via
} else if (this.currentShipViaRow) { } else if (this.currentShipViaRow) {
this.$set(this.currentShipViaRow, 'shipVia', via) this.$set(this.currentShipViaRow, 'shipVia', via)
this.$set(this.currentShipViaRow, 'shipViaCode', data.method_no || data.methodNo || '') this.$set(this.currentShipViaRow, 'shipViaCode', data.method_no || data.methodNo || '')
@ -2379,8 +2580,12 @@ export default {
return Number.isInteger(total) ? String(total) : String(Number(total.toFixed(4))) return Number.isInteger(total) ? String(total) : String(Number(total.toFixed(4)))
}, },
recalcAddFormValue () {
this.addForm.value = this.calcPoValue(this.addForm.price, this.addForm.qty)
recalcAddFormValue (target = 'master') {
const form = this.getAddTargetForm(target)
if (!form) {
return
}
this.$set(form, 'value', this.calcPoValue(form.price, form.qty))
}, },
validatePriceAndQty (price, qty, label) { validatePriceAndQty (price, qty, label) {
@ -2958,10 +3163,14 @@ export default {
} }
}, },
openSupplierPartDialog (context, row = null) { openSupplierPartDialog (context, row = null) {
const site = String((context === 'row' ? (row && row.site) : this.searchData.site) || this.$store.state.user.site || '').trim()
const site = String((context === 'row'
? (row && row.site)
: (context === 'addDetail' ? this.addDetailForm.site : this.searchData.site)) || this.$store.state.user.site || '').trim()
const supplierNo = String((context === 'row' const supplierNo = String((context === 'row'
? (row && (row.supplierNo || row.supplier_no || row.supplierCode || row.supplier_code)) ? (row && (row.supplierNo || row.supplier_no || row.supplierCode || row.supplier_code))
: this.addForm.supplierNo) || '').trim()
: (context === 'addDetail'
? (this.addDetailForm.supplierNo || this.addForm.supplierNo || '')
: this.addForm.supplierNo)) || '').trim()
if (!site) { if (!site) {
this.$message.warning('请先选择site') this.$message.warning('请先选择site')
return return
@ -3009,7 +3218,10 @@ export default {
} }
if (this.supplierPartDialogContext === 'add') { if (this.supplierPartDialogContext === 'add') {
this.applySelectedPartToTarget(this.addForm, row, false) this.applySelectedPartToTarget(this.addForm, row, false)
this.scheduleAutoFillAddPriceByTierPrice()
this.scheduleAutoFillAddPriceByTierPrice('master')
} else if (this.supplierPartDialogContext === 'addDetail') {
this.applySelectedPartToTarget(this.addDetailForm, row, false)
this.scheduleAutoFillAddPriceByTierPrice('detail')
} else if (this.supplierPartDialogContext === 'row' && this.supplierPartDialogTargetRow) { } else if (this.supplierPartDialogContext === 'row' && this.supplierPartDialogTargetRow) {
this.applySelectedPartToTarget(this.supplierPartDialogTargetRow, row, true) this.applySelectedPartToTarget(this.supplierPartDialogTargetRow, row, true)
} }
@ -3043,6 +3255,12 @@ export default {
this.addPriceLookupSeq += 1 this.addPriceLookupSeq += 1
this.addForm = this.createEmptyAddForm(this.resolveAddOrderTypeByCustomer()) this.addForm = this.createEmptyAddForm(this.resolveAddOrderTypeByCustomer())
this.addForm.customer = this.searchData.customer this.addForm.customer = this.searchData.customer
this.addDetailRows = []
this.addDetailCurrentDraftId = ''
this.addDetailDialogMode = 'create'
this.addDetailDialogVisible = false
this.addDetailEditingDraftId = ''
this.addDetailForm = this.createEmptyAddDetailForm()
this.addDialogVisible = true this.addDialogVisible = true
this.loadAddFieldSchema(this.searchData.customer) this.loadAddFieldSchema(this.searchData.customer)
if (!this.poPartNoOptions.length) { if (!this.poPartNoOptions.length) {
@ -3063,6 +3281,7 @@ export default {
if (data && data.code === 0 && data.data) { if (data && data.code === 0 && data.data) {
this.addFormSchemaFields = data.data.fields || [] this.addFormSchemaFields = data.data.fields || []
this.applyAddDefaultDateBySchema() this.applyAddDefaultDateBySchema()
this.addDetailForm = this.createEmptyAddDetailForm()
} else { } else {
this.addFormSchemaFields = [] this.addFormSchemaFields = []
} }
@ -3081,34 +3300,56 @@ export default {
}, },
applyAddDefaultDateBySchema () { applyAddDefaultDateBySchema () {
if (!Array.isArray(this.addFormSchemaFields) || !this.addFormSchemaFields.length) {
this.applyDefaultDateBySchemaToForm(this.addForm)
},
applyDefaultDateBySchemaToForm (targetForm) {
if (!targetForm || !Array.isArray(this.addFormSchemaFields) || !this.addFormSchemaFields.length) {
return return
} }
const today = this.getTodayDateYmd() const today = this.getTodayDateYmd()
this.addFormSchemaFields.forEach(field => { this.addFormSchemaFields.forEach(field => {
const code = this.getAddFieldCode(field)
const prop = this.getAddFieldProp(field) const prop = this.getAddFieldProp(field)
if (!code || !prop) {
if (!prop) {
return return
} }
if (ADD_READONLY_DEFAULT_TODAY_FIELD_CODES.has(code) || ADD_EDITABLE_DEFAULT_TODAY_FIELD_CODES.has(code)) {
this.$set(this.addForm, prop, today)
if (this.isAddCreateDateField(field) || this.isAddPoPlaceDateField(field)) {
this.$set(targetForm, prop, today)
} }
}) })
}, },
getAddExtValue (fieldCode) {
if (!this.addForm.extValues) {
getFormExtValue (targetForm, fieldCode) {
if (!targetForm || !targetForm.extValues) {
return '' return ''
} }
return this.addForm.extValues[fieldCode] == null ? '' : this.addForm.extValues[fieldCode]
return targetForm.extValues[fieldCode] == null ? '' : targetForm.extValues[fieldCode]
}, },
setAddExtValue (fieldCode, val) {
if (!this.addForm.extValues) {
this.$set(this.addForm, 'extValues', {})
setFormExtValue (targetForm, fieldCode, val) {
if (!targetForm) {
return
}
if (!targetForm.extValues) {
this.$set(targetForm, 'extValues', {})
} }
this.$set(this.addForm.extValues, fieldCode, val)
this.$set(targetForm.extValues, fieldCode, val)
},
getAddExtValue (fieldCode) {
return this.getFormExtValue(this.addForm, fieldCode)
},
setAddExtValue (fieldCode, val) {
this.setFormExtValue(this.addForm, fieldCode, val)
},
getAddDetailExtValue (fieldCode) {
return this.getFormExtValue(this.addDetailForm, fieldCode)
},
setAddDetailExtValue (fieldCode, val) {
this.setFormExtValue(this.addDetailForm, fieldCode, val)
}, },
createEmptyAddForm (orderType = '采购订单') { createEmptyAddForm (orderType = '采购订单') {
@ -3135,7 +3376,7 @@ export default {
departure: '', departure: '',
destination: '', destination: '',
shipVia: '', shipVia: '',
orderDate: today,
orderDate: '',
enquiry: '', enquiry: '',
status: '草稿', status: '草稿',
confirmed: '', confirmed: '',
@ -3144,7 +3385,7 @@ export default {
crd: '', crd: '',
inspection: '', inspection: '',
realCrd: '', realCrd: '',
poPlaceDate: today,
poPlaceDate: '',
poPromiseReadyDate: '', poPromiseReadyDate: '',
poActualReadyDate: '', poActualReadyDate: '',
chinaOfficeInspectionDate: '', chinaOfficeInspectionDate: '',
@ -3163,62 +3404,297 @@ export default {
} }
}, },
openAddSupplierSelect () {
createEmptyAddDetailForm () {
const form = this.createEmptyAddForm(this.addForm.orderType || this.resolveAddOrderTypeByCustomer())
form.customer = this.searchData.customer || form.customer
form.site = this.searchData.site || this.$store.state.user.site
this.applyDefaultDateBySchemaToForm(form)
return form
},
cloneAddDraftRow (row) {
const cloned = JSON.parse(JSON.stringify(row || {}))
if (!cloned.extValues || typeof cloned.extValues !== 'object') {
cloned.extValues = {}
}
return cloned
},
buildAddDetailRowFromForm () {
const row = this.cloneAddDraftRow(this.addDetailForm)
if (!row._draftId) {
this.addDetailDraftSeq += 1
row._draftId = `DRAFT_${Date.now()}_${this.addDetailDraftSeq}`
}
row.value = this.calcPoValue(row.price, row.qty)
return row
},
getSelectedAddDetailRow () {
if (!this.addDetailCurrentDraftId) {
return null
}
return this.addDetailRows.find(row => row && row._draftId === this.addDetailCurrentDraftId) || null
},
onAddDetailCurrentChange (row) {
this.addDetailCurrentDraftId = row && row._draftId ? row._draftId : ''
},
onAddDetailRowClick (row) {
this.addDetailCurrentDraftId = row && row._draftId ? row._draftId : ''
if (this.$refs.addDetailTable && this.$refs.addDetailTable.setCurrentRow) {
this.$refs.addDetailTable.setCurrentRow(row)
}
},
openAddDetailDialog () {
this.addDetailDialogMode = 'create'
this.addDetailEditingDraftId = ''
this.addDetailForm = this.createEmptyAddDetailForm()
this.addDetailDialogVisible = true
},
openEditAddDetailDialog () {
const selected = this.getSelectedAddDetailRow()
if (!selected) {
this.$message.warning('请先选择一条明细')
return
}
this.addDetailDialogMode = 'edit'
this.addDetailEditingDraftId = selected._draftId
this.addDetailForm = this.cloneAddDraftRow(selected)
this.addDetailDialogVisible = true
},
openCopyAddDetailDialog () {
const selected = this.getSelectedAddDetailRow()
if (!selected) {
this.$message.warning('请先选择一条明细')
return
}
const copied = this.cloneAddDraftRow(selected)
copied._draftId = ''
copied.partNo = ''
this.addDetailDialogMode = 'copy'
this.addDetailEditingDraftId = ''
this.addDetailForm = copied
this.addDetailDialogVisible = true
},
removeAddDetailRow () {
const selected = this.getSelectedAddDetailRow()
if (!selected) {
this.$message.warning('请先选择一条明细')
return
}
this.addDetailRows = this.addDetailRows.filter(row => row && row._draftId !== selected._draftId)
this.addDetailCurrentDraftId = ''
this.$nextTick(() => {
if (this.$refs.addDetailTable && this.$refs.addDetailTable.setCurrentRow) {
this.$refs.addDetailTable.setCurrentRow(null)
}
})
},
isAddFormFieldEmpty (value) {
if (value === null || value === undefined) {
return true
}
if (typeof value === 'string') {
return value.trim() === ''
}
return false
},
validateRequiredFieldGroup (fields, form, prefixLabel = '') {
if (!Array.isArray(fields)) {
return true
}
for (const field of fields) {
if (!field || field.requiredFlag !== 'Y') {
continue
}
const prop = this.getAddFieldProp(field)
if (!prop) {
continue
}
const value = form ? form[prop] : null
if (this.isAddFormFieldEmpty(value)) {
this.$message.warning(`${prefixLabel}${field.fieldLabel}不能为空`)
return false
}
}
return true
},
validateRequiredExtFieldGroup (fields, form, prefixLabel = '') {
if (!Array.isArray(fields)) {
return true
}
for (const field of fields) {
if (!field || field.requiredFlag !== 'Y') {
continue
}
const fieldCode = String((field && field.fieldCode) || '').trim()
if (!fieldCode) {
continue
}
const value = this.getFormExtValue(form, fieldCode)
if (this.isAddFormFieldEmpty(value)) {
this.$message.warning(`${prefixLabel}${field.fieldLabel}不能为空`)
return false
}
}
return true
},
saveAddDetailDraft () {
if (!this.validateRequiredFieldGroup(this.addDetailBaseFields, this.addDetailForm, '明细:')) {
return
}
if (!this.validateRequiredExtFieldGroup(this.addDetailExtFields, this.addDetailForm, '明细:')) {
return
}
const nextRow = this.buildAddDetailRowFromForm()
if (this.addDetailDialogMode === 'edit' && this.addDetailEditingDraftId) {
const targetIndex = this.addDetailRows.findIndex(row => row && row._draftId === this.addDetailEditingDraftId)
if (targetIndex >= 0) {
nextRow._draftId = this.addDetailEditingDraftId
this.$set(this.addDetailRows, targetIndex, nextRow)
}
} else {
this.addDetailRows.push(nextRow)
}
this.addDetailCurrentDraftId = nextRow._draftId
this.addDetailDialogVisible = false
this.$nextTick(() => {
if (this.$refs.addDetailTable && this.$refs.addDetailTable.setCurrentRow) {
const selected = this.addDetailRows.find(row => row && row._draftId === nextRow._draftId) || null
this.$refs.addDetailTable.setCurrentRow(selected)
}
})
},
openAddSupplierSelect (target = 'master') {
const conSql = " and site = '" + this.$store.state.user.site + "'" const conSql = " and site = '" + this.$store.state.user.site + "'"
this.openEamList(SUPPLIER_CHOOSELIST_TAG, '', conSql, 'add', 'supplier')
const context = target === 'detail' ? 'addDetail' : 'add'
this.openEamList(SUPPLIER_CHOOSELIST_TAG, '', conSql, context, 'supplier')
},
openAddPartNoSelect (target = 'master') {
this.openSupplierPartDialog(target === 'detail' ? 'addDetail' : 'add')
}, },
openAddPartNoSelect () {
this.openSupplierPartDialog('add')
openAddDepartureSelect (target = 'master') {
const context = target === 'detail' ? 'addDetail' : 'add'
this.openEamList(2018, '', this.buildDeparturePortConSql(), context, 'departure')
}, },
openAddDepartureSelect () {
this.openEamList(2018, '', this.buildDeparturePortConSql(), 'add', 'departure')
openAddDestinationSelect (target = 'master') {
const context = target === 'detail' ? 'addDetail' : 'add'
this.openEamList(2018, '', this.buildDestinationPortConSql(), context, 'destination')
}, },
openAddDestinationSelect () {
this.openEamList(2018, '', this.buildDestinationPortConSql(), 'add', 'destination')
openAddShipViaSelect (target = 'master') {
const context = target === 'detail' ? 'addDetail' : 'add'
this.openEamList(2019, '', '', context, 'shipVia')
}, },
openAddShipViaSelect () {
this.openEamList(2019, '', '', 'add', 'shipVia')
buildMergedAddDetailForm (detailRow) {
const merged = {}
this.addMasterBaseFields.forEach(field => {
const prop = this.getAddFieldProp(field)
if (!prop) return
merged[prop] = this.addForm[prop]
})
this.addDetailBaseFields.forEach(field => {
const prop = this.getAddFieldProp(field)
if (!prop) return
merged[prop] = detailRow ? detailRow[prop] : null
})
merged.customer = this.searchData.customer || this.addForm.customer || ''
merged.extValues = { ...(detailRow && detailRow.extValues ? detailRow.extValues : {}) }
return merged
}, },
saveAddPoOrder () { saveAddPoOrder () {
if (!this.addForm.poNo || !this.addForm.supplierName || !this.addForm.partNo) {
this.$message.warning('请填写 PO No、Vendor Name、Part No')
if (!this.validateRequiredFieldGroup(this.addMasterBaseFields, this.addForm, '主记录:')) {
return
}
if (!this.addForm.poNo || String(this.addForm.poNo).trim() === '') {
this.$message.warning('主记录:请填写 PO No')
return return
} }
if (!this.validatePriceAndQty(this.addForm.price, this.addForm.qty)) {
if ((!this.addForm.supplierName || String(this.addForm.supplierName).trim() === '') &&
(!this.addForm.supplierNo || String(this.addForm.supplierNo).trim() === '')) {
this.$message.warning('主记录:请填写 Vendor Name')
return return
} }
this.recalcAddFormValue()
if (this.addDetailRows.length === 0) {
this.$message.warning('请至少新增一条明细')
return
}
const payloadList = []
for (let i = 0; i < this.addDetailRows.length; i++) {
const row = this.addDetailRows[i]
if (!this.validateRequiredFieldGroup(this.addDetailBaseFields, row, `${i + 1}行明细:`)) {
return
}
if (!this.validateRequiredExtFieldGroup(this.addDetailExtFields, row, `${i + 1}行明细:`)) {
return
}
const mergedForm = this.buildMergedAddDetailForm(row)
if (!mergedForm.partNo || String(mergedForm.partNo).trim() === '') {
this.$message.warning(`${i + 1}行明细:请填写 Part No`)
return
}
if (!this.validatePriceAndQty(mergedForm.price, mergedForm.qty, `${i + 1}`)) {
return
}
const calculatedValue = this.calcPoValue(mergedForm.price, mergedForm.qty)
payloadList.push(this.buildAddPayload(calculatedValue, mergedForm, this.addBaseFields, this.addExtFields))
}
if (payloadList.length === 0) {
this.$message.warning('请至少新增一条明细')
return
}
this.addFormSaving = true this.addFormSaving = true
const calculatedValue = this.calcPoValue(this.addForm.price, this.addForm.qty)
const payload = this.buildAddPayload(calculatedValue)
createPoOrder(payload).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('新增成功')
this.addDialogVisible = false
this.getDataList()
} else {
this.$message.error((data && data.msg) || '新增失败')
const runCreate = (idx) => {
if (idx >= payloadList.length) {
return Promise.resolve()
} }
return createPoOrder(payloadList[idx]).then(({ data }) => {
if (data && data.code === 0) {
return runCreate(idx + 1)
}
const errMsg = (data && data.msg) || '新增失败'
throw new Error(`${idx + 1}行:${errMsg}`)
})
}
runCreate(0).then(() => {
this.$message.success(`新增成功,共 ${payloadList.length}`)
this.addDialogVisible = false
this.addDetailDialogVisible = false
this.getDataList()
}).catch(err => { }).catch(err => {
this.$message.error((err && err.message) || '新增失败') this.$message.error((err && err.message) || '新增失败')
}).finally(() => { }).finally(() => {
this.addFormSaving = false this.addFormSaving = false
}) })
}, },
buildAddPayload (calculatedValue) {
buildAddPayload (calculatedValue, sourceForm = this.addForm, baseFields = this.addBaseFields, extFields = this.addExtFields) {
const payload = { const payload = {
site: this.$store.state.user.site, site: this.$store.state.user.site,
customer: this.searchData.customer, customer: this.searchData.customer,
extValues: {} extValues: {}
} }
this.addBaseFields.forEach(field => {
baseFields.forEach(field => {
const prop = this.getAddFieldProp(field) const prop = this.getAddFieldProp(field)
const code = this.getAddFieldCode(field) const code = this.getAddFieldCode(field)
if (!prop || !code) { if (!prop || !code) {
return return
} }
let value = this.addForm[prop]
let value = sourceForm[prop]
if (code === 'customer') { if (code === 'customer') {
value = this.searchData.customer || value value = this.searchData.customer || value
} else if (code === 'value') { } else if (code === 'value') {
@ -3228,12 +3704,12 @@ export default {
} }
payload[prop] = value payload[prop] = value
}) })
this.addExtFields.forEach(field => {
extFields.forEach(field => {
const fieldCode = (field && field.fieldCode) ? String(field.fieldCode).trim() : '' const fieldCode = (field && field.fieldCode) ? String(field.fieldCode).trim() : ''
if (!fieldCode) { if (!fieldCode) {
return return
} }
const value = this.getAddExtValue(fieldCode)
const value = this.getFormExtValue(sourceForm, fieldCode)
if (value === '' || value === null || value === undefined) { if (value === '' || value === null || value === undefined) {
return return
} }
@ -3300,6 +3776,19 @@ export default {
.po-add-form-wrap /deep/ .el-form--label-top .el-form-item__label { .po-add-form-wrap /deep/ .el-form--label-top .el-form-item__label {
white-space: nowrap; white-space: nowrap;
} }
.po-add-detail-toolbar {
margin: 10px 0 8px;
display: flex;
justify-content: space-between;
align-items: center;
}
.po-add-detail-title {
font-size: 13px;
color: #606266;
}
.el-table /deep/ .cell { .el-table /deep/ .cell {
height: auto; height: auto;
line-height: 1.5; line-height: 1.5;

10
src/views/modules/srmSupplier/supplierList.vue

@ -191,7 +191,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="供应商文档类型" prop="supplierDocType">
<el-form-item label="供应商文档清单模板" prop="supplierDocType">
<el-select v-model="currentSupplier.supplierDocType" placeholder="请选择" filterable style="width: 100%"> <el-select v-model="currentSupplier.supplierDocType" placeholder="请选择" filterable style="width: 100%">
<el-option <el-option
v-for="item in supplierDocTypeOptions" v-for="item in supplierDocTypeOptions"
@ -506,7 +506,7 @@ export default {
columnProp: 'supplierDocType', columnProp: 'supplierDocType',
headerAlign: 'center', headerAlign: 'center',
align: 'center', align: 'center',
columnLabel: '供应商文档类型',
columnLabel: '供应商文档清单模板',
columnWidth: '150', columnWidth: '150',
columnHidden: false, columnHidden: false,
columnImage: false, columnImage: false,
@ -1191,7 +1191,7 @@ export default {
{ required: true, message: ' ', trigger: 'blur' } { required: true, message: ' ', trigger: 'blur' }
], ],
supplierDocType: [ supplierDocType: [
{ required: true, message: '请选择供应商文档类型', trigger: ['blur', 'change'] }
{ required: true, message: '请选择供应商文档清单模板', trigger: ['blur', 'change'] }
] ]
} }
} }
@ -1335,11 +1335,11 @@ export default {
} }
} else { } else {
this.supplierDocTypeOptions = [] this.supplierDocTypeOptions = []
this.$message.error((data && data.msg) || '加载供应商文档类型失败')
this.$message.error((data && data.msg) || '加载供应商文档清单失败')
} }
}).catch(() => { }).catch(() => {
this.supplierDocTypeOptions = [] this.supplierDocTypeOptions = []
this.$message.error('加载供应商文档类型失败')
this.$message.error('加载供应商文档清单失败')
}) })
}, },
getMainData (opts) { getMainData (opts) {

Loading…
Cancel
Save