Browse Source

新品流程OK

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

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

@ -295,21 +295,21 @@
:advanced-query-data="advancedQueryData"
@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>
<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-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'">
<template v-if="isAddChooserField(field)">
<el-input
v-model="addForm[getAddFieldProp(field)]"
readonly
: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>
</template>
<template v-else-if="isAddSelectField(field)">
@ -346,19 +346,119 @@
v-model="addForm[getAddFieldProp(field)]"
:type="isAddNumberField(field) ? 'number' : 'text'"
:disabled="isAddFieldDisabled(field)"
@input="onAddFieldInput(field)" />
@input="onAddFieldInput(field, 'master')" />
</template>
</el-form-item>
</el-col>
</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'">
<com-po-order-dynamic-field-renderer
:field="field"
: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-col>
@ -366,8 +466,8 @@
</el-form>
</div>
<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>
</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_NUMBER_FIELD_CODES = new Set(['price', 'qty', 'ship_qty', 'sum_price'])
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_SELECT_OPTIONS_FIELD_CODE_MAP = {
order_type: 'poOrderTypeOptions',
@ -531,6 +632,13 @@ export default {
eamTagNo: '',
eamPickField: '',
addForm: {},
addDetailDialogVisible: false,
addDetailDialogMode: 'create',
addDetailForm: {},
addDetailRows: [],
addDetailCurrentDraftId: '',
addDetailEditingDraftId: '',
addDetailDraftSeq: 0,
supplierPartDialogVisible: false,
supplierPartDialogLoading: false,
supplierPartDialogRows: [],
@ -1594,6 +1702,9 @@ export default {
addExtFields () {
return getEditableExtFieldsFromSchema(this.addFormSchemaFields)
},
addDetailExtFields () {
return this.addExtFields
},
addBaseFields () {
if (!Array.isArray(this.addFormSchemaFields)) {
return []
@ -1619,6 +1730,27 @@ export default {
})
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 () {
if (!this.uploadColumnMapping || typeof this.uploadColumnMapping !== 'object') {
return []
@ -1761,6 +1893,42 @@ export default {
const code = this.getAddFieldCode(field)
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) {
return String(text || '').replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase())
},
@ -1770,18 +1938,18 @@ export default {
isAddChooserField (field) {
return ADD_CHOOSER_FIELD_CODES.has(this.getAddFieldCode(field))
},
openAddChooserByField (field) {
openAddChooserByField (field, target = 'master') {
const code = this.getAddFieldCode(field)
if (code === 'supplier_name') {
this.openAddSupplierSelect()
this.openAddSupplierSelect(target)
} else if (code === 'part_no') {
this.openAddPartNoSelect()
this.openAddPartNoSelect(target)
} else if (code === 'departure') {
this.openAddDepartureSelect()
this.openAddDepartureSelect(target)
} else if (code === 'destination') {
this.openAddDestinationSelect()
this.openAddDestinationSelect(target)
} else if (code === 'ship_via') {
this.openAddShipViaSelect()
this.openAddShipViaSelect(target)
}
},
getAddChooserPlaceholder (field) {
@ -1834,7 +2002,7 @@ export default {
if (code === 'customer') {
return true
}
if (ADD_READONLY_DEFAULT_TODAY_FIELD_CODES.has(code)) {
if (this.isAddCreateDateField(field)) {
return true
}
if (ADD_DISPLAY_ONLY_FIELD_CODES.has(code)) {
@ -1849,33 +2017,50 @@ export default {
}
return this.isAddTextareaField(field) ? 12 : 6
},
onAddFieldInput (field) {
onAddFieldInput (field, target = 'master') {
const code = this.getAddFieldCode(field)
if (code === 'price' || code === 'qty') {
this.recalcAddFormValue()
this.recalcAddFormValue(target)
}
if (code === 'qty') {
this.scheduleAutoFillAddPriceByTierPrice()
this.scheduleAutoFillAddPriceByTierPrice(target)
}
},
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 () {
scheduleAutoFillAddPriceByTierPrice (target = 'master') {
if (this.addPriceLookupTimer) {
clearTimeout(this.addPriceLookupTimer)
this.addPriceLookupTimer = null
}
this.addPriceLookupTimer = setTimeout(() => {
this.addPriceLookupTimer = null
this.autoFillAddPriceByTierPrice()
this.autoFillAddPriceByTierPrice(target)
}, 250)
},
autoFillAddPriceByTierPrice () {
autoFillAddPriceByTierPrice (target = 'master') {
if (!this.addDialogVisible) {
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 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) {
return Promise.resolve()
}
@ -1903,8 +2088,8 @@ export default {
if (normalizedPrice === '') {
return
}
this.$set(this.addForm, 'price', normalizedPrice)
this.recalcAddFormValue()
this.$set(targetForm, 'price', normalizedPrice)
this.recalcAddFormValue(target)
}).catch(() => {})
},
findCurrentTierPriceByQty (rows, qty) {
@ -2253,7 +2438,11 @@ export default {
const { supplierNo, supplierName } = parseSupplierChooselistRow(data)
if (ctx === 'add') {
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) {
const row = this.currentSelectRow
@ -2268,7 +2457,11 @@ export default {
if (ctx === 'add') {
this.$set(this.addForm, 'partNo', partNo)
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) {
this.$set(this.currentPartNoRow, 'partNo', partNo)
this.fillPartCategorySku(partNo, this.currentPartNoRow)
@ -2289,6 +2482,12 @@ export default {
} else if (this.eamPickField === 'destination') {
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) {
this.$set(this.currentDepartureRow, 'departure', code)
this.$set(this.currentDepartureRow, 'departureName', portName)
@ -2306,6 +2505,8 @@ export default {
const via = data.method_desc || data.methodDesc || data.shipVia || ''
if (ctx === 'add') {
this.addForm.shipVia = via
} else if (ctx === 'addDetail') {
this.addDetailForm.shipVia = via
} else if (this.currentShipViaRow) {
this.$set(this.currentShipViaRow, 'shipVia', via)
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)))
},
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) {
@ -2958,10 +3163,14 @@ export default {
}
},
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'
? (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) {
this.$message.warning('请先选择site')
return
@ -3009,7 +3218,10 @@ export default {
}
if (this.supplierPartDialogContext === 'add') {
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) {
this.applySelectedPartToTarget(this.supplierPartDialogTargetRow, row, true)
}
@ -3043,6 +3255,12 @@ export default {
this.addPriceLookupSeq += 1
this.addForm = this.createEmptyAddForm(this.resolveAddOrderTypeByCustomer())
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.loadAddFieldSchema(this.searchData.customer)
if (!this.poPartNoOptions.length) {
@ -3063,6 +3281,7 @@ export default {
if (data && data.code === 0 && data.data) {
this.addFormSchemaFields = data.data.fields || []
this.applyAddDefaultDateBySchema()
this.addDetailForm = this.createEmptyAddDetailForm()
} else {
this.addFormSchemaFields = []
}
@ -3081,34 +3300,56 @@ export default {
},
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
}
const today = this.getTodayDateYmd()
this.addFormSchemaFields.forEach(field => {
const code = this.getAddFieldCode(field)
const prop = this.getAddFieldProp(field)
if (!code || !prop) {
if (!prop) {
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 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
}
this.$set(this.addForm.extValues, fieldCode, val)
if (!targetForm.extValues) {
this.$set(targetForm, 'extValues', {})
}
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 = '采购订单') {
@ -3135,7 +3376,7 @@ export default {
departure: '',
destination: '',
shipVia: '',
orderDate: today,
orderDate: '',
enquiry: '',
status: '草稿',
confirmed: '',
@ -3144,7 +3385,7 @@ export default {
crd: '',
inspection: '',
realCrd: '',
poPlaceDate: today,
poPlaceDate: '',
poPromiseReadyDate: '',
poActualReadyDate: '',
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 + "'"
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 () {
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.validatePriceAndQty(this.addForm.price, this.addForm.qty)) {
if (!this.addForm.poNo || String(this.addForm.poNo).trim() === '') {
this.$message.warning('主记录:请填写 PO No')
return
}
this.recalcAddFormValue()
if ((!this.addForm.supplierName || String(this.addForm.supplierName).trim() === '') &&
(!this.addForm.supplierNo || String(this.addForm.supplierNo).trim() === '')) {
this.$message.warning('主记录:请填写 Vendor Name')
return
}
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
const calculatedValue = this.calcPoValue(this.addForm.price, this.addForm.qty)
const payload = this.buildAddPayload(calculatedValue)
createPoOrder(payload).then(({ data }) => {
const runCreate = (idx) => {
if (idx >= payloadList.length) {
return Promise.resolve()
}
return createPoOrder(payloadList[idx]).then(({ data }) => {
if (data && data.code === 0) {
this.$message.success('新增成功')
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()
} else {
this.$message.error((data && data.msg) || '新增失败')
}
}).catch(err => {
this.$message.error((err && err.message) || '新增失败')
}).finally(() => {
this.addFormSaving = false
})
},
buildAddPayload (calculatedValue) {
buildAddPayload (calculatedValue, sourceForm = this.addForm, baseFields = this.addBaseFields, extFields = this.addExtFields) {
const payload = {
site: this.$store.state.user.site,
customer: this.searchData.customer,
extValues: {}
}
this.addBaseFields.forEach(field => {
baseFields.forEach(field => {
const prop = this.getAddFieldProp(field)
const code = this.getAddFieldCode(field)
if (!prop || !code) {
return
}
let value = this.addForm[prop]
let value = sourceForm[prop]
if (code === 'customer') {
value = this.searchData.customer || value
} else if (code === 'value') {
@ -3228,12 +3704,12 @@ export default {
}
payload[prop] = value
})
this.addExtFields.forEach(field => {
extFields.forEach(field => {
const fieldCode = (field && field.fieldCode) ? String(field.fieldCode).trim() : ''
if (!fieldCode) {
return
}
const value = this.getAddExtValue(fieldCode)
const value = this.getFormExtValue(sourceForm, fieldCode)
if (value === '' || value === null || value === undefined) {
return
}
@ -3300,6 +3776,19 @@ export default {
.po-add-form-wrap /deep/ .el-form--label-top .el-form-item__label {
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 {
height: auto;
line-height: 1.5;

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

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

Loading…
Cancel
Save