queryPart.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. <template>
  2. <div class="productInfoList-wrap">
  3. <!-- 搜索条件 -->
  4. <div class="table-page-search-wrapper">
  5. <a-form layout="inline" @keyup.enter.native="searchTable">
  6. <a-row :gutter="15">
  7. <a-col :md="4" :sm="24">
  8. <a-form-item label="产品名称">
  9. <a-input id="productInfoList-name" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
  10. </a-form-item>
  11. </a-col>
  12. <a-col :md="4" :sm="24">
  13. <a-form-item label="产品编码">
  14. <a-input id="productInfoList-code" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
  15. </a-form-item>
  16. </a-col>
  17. <a-col :md="4" :sm="24" v-if="hasPrompActive">
  18. <a-form-item label="产品类型">
  19. <a-select allowClear v-model.trim="queryParam.promotionFlag" :dropdownMatchSelectWidth="false" placeholder="请选择产品类型">
  20. <a-select-option value="0">
  21. 正常产品
  22. </a-select-option>
  23. <a-select-option value="REGULAR">
  24. 正价产品(活动)
  25. </a-select-option>
  26. <a-select-option value="DISCOUNT">
  27. 特价产品
  28. </a-select-option>
  29. <a-select-option value="GIFT">
  30. 促销产品
  31. </a-select-option>
  32. <a-select-option value="convertPromoGiftsFlag" v-if="showConvertPromoGifts">
  33. 促销产品(转采购额)
  34. </a-select-option>
  35. <a-select-option value="GATE">
  36. 门槛产品
  37. </a-select-option>
  38. </a-select>
  39. </a-form-item>
  40. </a-col>
  41. <a-col :md="4" :sm="24">
  42. <a-form-item label="下推类型">
  43. <a-select allowClear v-model.trim="queryParam.pushProductType" :dropdownMatchSelectWidth="false" placeholder="请选择下推类型">
  44. <a-select-option value="">
  45. 全部产品
  46. </a-select-option>
  47. <a-select-option value="ABLE">
  48. 剩余待下推数量>0的产品
  49. </a-select-option>
  50. <a-select-option value="ALL">
  51. 可全部下推的产品
  52. </a-select-option>
  53. <a-select-option value="NOTALL">
  54. 不可全部下推的产品
  55. </a-select-option>
  56. </a-select>
  57. </a-form-item>
  58. </a-col>
  59. <a-col :md="4" :sm="24">
  60. <a-form-item label="出库仓库">
  61. <chooseWarehouse ref="warehouse" v-model="queryParam.warehouseSn"></chooseWarehouse>
  62. </a-form-item>
  63. </a-col>
  64. <a-col :md="4" :sm="24" style="margin-bottom: 10px;">
  65. <a-button type="primary" @click="searchTable" :disabled="disabled" id="productInfoList-refresh">查询</a-button>
  66. <a-button style="margin-left: 5px" @click="resetSearchForm(null)" id="productInfoList-reset">重置</a-button>
  67. </a-col>
  68. </a-row>
  69. </a-form>
  70. </div>
  71. <!-- alert -->
  72. <div style="margin-bottom: 10px;display: flex;align-items: center;" v-if="detailData">
  73. <div style="display: flex;align-items: center;">
  74. <a-button id="dispatch-plAdd" type="primary" :disabled="newLoading" class="button-info" @click="handlePlAdd">批量添加</a-button>
  75. <a-button
  76. id="dispatch-plPurchase"
  77. type="primary"
  78. :disabled="newLoading"
  79. class="button-info"
  80. v-if="showConvertPromoGifts"
  81. @click="handlePlPurchase">批量转采购额</a-button>
  82. <a-button
  83. id="dispatch-plCancel"
  84. type="primary"
  85. v-if="hasNormalProduct"
  86. ghost
  87. style="margin-left:6px;"
  88. :disabled="newLoading"
  89. @click="handlePlCancel">批量取消</a-button>
  90. <a-button
  91. id="dispatch-cancelAll"
  92. type="primary"
  93. v-if="hasPrompActive&&hasNoPushedActive"
  94. ghost
  95. style="margin-left:6px;"
  96. :disabled="newLoading"
  97. @click="handleAllCancel">整单取消</a-button>
  98. <a-tooltip placement="top" v-if="hasPrompActive&&hasNoPushedActive" style="margin-left:6px;">
  99. <template slot="title">
  100. <span>参加促销活动的产品,不能单独取消,只能整单取消。</span>
  101. </template>
  102. <a-icon style="font-size: 14px;" type="question-circle" />
  103. </a-tooltip>
  104. <span style="margin-left: 10px;" v-if="selectedRowKeys.length">已选 {{ selectedRowKeys.length }} 项</span>
  105. <a-button
  106. @click="confirPurchaseModal"
  107. :loading="loading"
  108. type="primary"
  109. style="margin-left: 15px"
  110. class="button-info"
  111. id="dispatch-updateStock">整单转采购单</a-button>
  112. </div>
  113. <div style="padding-left: 20px;">
  114. 总销售数量:<strong>{{ detailData&&(detailData.totalQty || detailData.totalQty==0) ? detailData.totalQty : '--' }}</strong>;
  115. 已取消数量:<strong>{{ detailData&&(detailData.totalCancelQty || detailData.totalCancelQty==0) ? detailData.totalCancelQty : '--' }}</strong>;
  116. 已下推数量:<strong>{{ detailData&&(detailData.totalPushedQty || detailData.totalPushedQty==0) ? detailData.totalPushedQty : '--' }}</strong>;
  117. 待下推数量:<strong>{{ detailData&&(detailData.totalUnpushedQty || detailData.totalUnpushedQty==0) ? detailData.totalUnpushedQty : '--' }}</strong>;
  118. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">总售价:<strong>{{ detailData&&(detailData.totalAmount || detailData.totalAmount==0) ? toThousands(detailData.totalAmount) : '--' }}</strong>;</span>
  119. <span v-if="$hasPermissions('B_salesDispatch_costPrice')">总成本:<strong>{{ detailData&&(detailData.totalCost || detailData.totalCost==0) ? toThousands(detailData.totalCost) : '--' }}</strong>;</span>
  120. <span v-if="$hasPermissions('B_salesDispatch_costPrice')&&$hasPermissions('B_salesDispatch_salesPrice')">总毛利:<strong>{{ detailData&&(detailData.grossProfit || detailData.grossProfit==0) ? toThousands(detailData.grossProfit) : '--' }}</strong>;</span>
  121. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已取消金额:<strong>{{ detailData&&(detailData.totalCancelAmount || detailData.totalCancelAmount==0) ? toThousands(detailData.totalCancelAmount) : '--' }}</strong>;</span>
  122. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">已下推金额:<strong>{{ detailData&&(detailData.totalPushedAmount || detailData.totalPushedAmount==0) ? toThousands(detailData.totalPushedAmount) :'--' }}</strong>;</span>
  123. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')">待下推金额:<strong>{{ detailData&&(detailData.totalUnpushedAmount || detailData.totalUnpushedAmount==0) ? toThousands(detailData.totalUnpushedAmount) : '--' }}</strong>;</span>
  124. <span v-if="$hasPermissions('B_salesDispatch_salesPrice')&&detailData&&detailData.totalConvertPromoGiftsAmount" style="color:red;">促销产品转采购额金额:<strong>{{ toThousands(detailData.totalConvertPromoGiftsAmount) }}</strong>;</span>
  125. </div>
  126. </div>
  127. <a-spin :spinning="spinning" tip="Loading...">
  128. <ve-table
  129. border-y
  130. v-show="!showEmpty"
  131. :scroll-width="0"
  132. :max-height="tableHeight"
  133. :show-header="showTableHead"
  134. :row-style-option="{clickHighlight: true}"
  135. :cellSelectionOption="{enable: false}"
  136. :virtual-scroll-option="{enable: true}"
  137. :columns="columns"
  138. :table-data="tableData"
  139. row-key-field-name="id"
  140. :cell-style-option="cellStyleOption"
  141. :cell-span-option="cellSpanOption"
  142. :column-width-resize-option="columnWidthResizeOption"
  143. :checkbox-option="checkboxOption"
  144. />
  145. <div v-show="showEmpty" class="empty-data"><a-empty description="暂无产品" :image="simpleImage"/></div>
  146. <!-- 活动规则详情 -->
  147. <detailModal :openModal="openDetailModal" :itemSn="detailSn" @close="closeDetailModal"></detailModal>
  148. <!-- 转采购单 -->
  149. <toPurchaseModal :openModal="openPurchaseModal" @ok="showLockStockQty = true" @close="openPurchaseModal=false" ref="purchaseModal"></toPurchaseModal>
  150. </a-spin>
  151. </div>
  152. </template>
  153. <script>
  154. import { commonMixin } from '@/utils/mixin'
  155. import { STable, VSelect } from '@/components'
  156. import { Empty } from 'ant-design-vue'
  157. import detailModal from '@/views/promotionRulesManagement/dealerPromotions/detailModal.vue'
  158. import toPurchaseModal from './toPurchaseModal'
  159. import chooseWarehouse from '@/views/common/chooseWarehouse'
  160. // 接口
  161. import { salesDetailAllList, salesPromoDetailCount, salesDetaiCount } from '@/api/salesDetailNew'
  162. import { salesPromoQueryList, getCreatePurchaseFlag } from '@/api/salesNew'
  163. export default {
  164. name: 'QueryPart',
  165. mixins: [commonMixin],
  166. components: { STable, VSelect, chooseWarehouse, detailModal, toPurchaseModal },
  167. props: {
  168. newLoading: { // loading
  169. type: Boolean,
  170. default: false
  171. },
  172. maxHeight: { // 最大高度
  173. type: [String, Number],
  174. default: '300'
  175. },
  176. showHeader: { // 是否显示表格头部
  177. type: Boolean,
  178. default: true
  179. }
  180. },
  181. data () {
  182. return {
  183. loading: false,
  184. advanced: true, // 高级搜索 展开/关闭
  185. openDetailModal: false, // 活动规则详情弹框
  186. openPurchaseModal: false, // 转采购单弹框
  187. simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
  188. detailSn: null, // 活动详情sn
  189. productType: [], // 产品类型
  190. salesBillSn: '', // 销售单sn
  191. detailData: null, // 详情数据
  192. queryParam: {
  193. pushProductType: '', // 类型
  194. productCode: '', // 产品编码
  195. productName: '', // 产品名称
  196. promotionFlag: undefined, // 是否促销品
  197. brandSn: undefined, // 产品品牌
  198. productTypeSn1: '', // 产品一级分类
  199. productTypeSn2: '', // 产品二级分类
  200. productTypeSn3: '', // 产品三级分类
  201. salesBillSn: '', // 销售单sn
  202. warehouseSn: undefined, // 仓库sn
  203. convertPromoGiftsFlag: undefined // 转采购额
  204. },
  205. disabled: false, // 查询、重置按钮是否可操作
  206. activeList: [], // 活动列表
  207. spinning: false,
  208. dataSource: [], // 原始数据
  209. tableData: [], // 表格数据
  210. cellStyleOption: {
  211. bodyCellClass: ({ row, column, rowIndex }) => {
  212. if (row.id.indexOf('promo-') >= 0 && column.field === 'no') {
  213. return 'table-body-cell-no'
  214. }
  215. }
  216. },
  217. // 可拖曳调整列宽
  218. columnWidthResizeOption: {
  219. enable: true,
  220. minWidth: 50
  221. },
  222. // 自定义单元格
  223. cellSpanOption: {
  224. bodyCellSpan: this.bodyCellSpan
  225. },
  226. showEmpty: false, // 空图片
  227. showTableHead: true, // 表格头部
  228. disableSelectedRowKeys: [], // 禁用数据
  229. selectedRowKeys: [], // 已选数据
  230. colspanNums: 16, // 列合并数量
  231. hasNormalProduct: false, // 是否有正常产品
  232. showLockStockQty: false // 是否显示锁定库存列
  233. }
  234. },
  235. computed: {
  236. // 表格高度
  237. tableHeight () {
  238. return (this.showEmpty ? 200 : this.maxHeight) + 'px'
  239. },
  240. // 是否有促销活动产品
  241. hasPrompActive () {
  242. return this.detailData && this.detailData.promoFlag == 1
  243. },
  244. // 是否有下推产品
  245. hasNoPushedActive () {
  246. return this.detailData && this.detailData.totalPushedQty == 0 || !this.detailData.totalPushedQty
  247. },
  248. // 是否有转采购额
  249. hasConvertPromoGifts () {
  250. return this.detailData && this.detailData.totalConvertPromoGiftsAmount > 0
  251. },
  252. // 是否显示转采购额选项
  253. showConvertPromoGifts () {
  254. return this.activeList && this.activeList.find(item => item.promotionRule && item.promotionRule.convertExpenseFlag == 1 && item.promotionRule.promotionRuleType == 'BUY_PROD_GIVE_PROD')
  255. },
  256. // 表格复选框
  257. checkboxOption () {
  258. return {
  259. disableSelectedRowKeys: this.disableSelectedRowKeys,
  260. selectedRowKeys: this.selectedRowKeys,
  261. // 行选择改变事件
  262. selectedRowChange: ({ row, isSelected, selectedRowKeys }) => {
  263. this.selectedRowChange({ row, isSelected, selectedRowKeys })
  264. },
  265. // 全选改变事件
  266. selectedAllChange: ({ isSelected, selectedRowKeys }) => {
  267. this.selectedAllChange({ isSelected, selectedRowKeys })
  268. }
  269. }
  270. },
  271. columns () {
  272. const _this = this
  273. // 价格
  274. const priceFormat = function (record, data, h) {
  275. return (
  276. <div>
  277. {_this.toThousands(data)}
  278. {record.promotionFlag == 'GIFT' || record.promotionFlag == 'DISCOUNT' ? (
  279. <span title="原价">({ _this.toThousands(record.origPrice)})</span>
  280. ) : ''}
  281. </div>
  282. )
  283. }
  284. // 数字
  285. const numsFormat = function (data) {
  286. return data || data == 0 ? data : '--'
  287. }
  288. // 单号
  289. const codeFormat = function (record, data, h) {
  290. let ftext = ''
  291. let fcolor = ''
  292. if (record.promotionFlag == 'GIFT') {
  293. ftext = '促'
  294. fcolor = '#52c41a'
  295. }
  296. if (record.promotionFlag == 'GATE') {
  297. ftext = '槛'
  298. fcolor = '#108ee9'
  299. }
  300. return (
  301. <div>
  302. <span style="padding-right: 15px;">{data}</span>
  303. {ftext ? (<a-badge count={ftext} number-style={{ backgroundColor: fcolor, zoom: '80%' }}></a-badge>) : ''}
  304. {record.bakConvertPromoGiftsQty ? (<a-badge count="转" number-style={{ backgroundColor: '#ffaa00', zoom: '80%' }}></a-badge>) : ''}
  305. {Number(record.stockQty || 0) < Number(record.unpushedQty || 0) ? (<a-badge count="缺" number-style={{ zoom: '80%' }}></a-badge>) : ''}
  306. </div>
  307. )
  308. }
  309. // 取消数量输入框
  310. const inputFormat = function (record, data, h) {
  311. if (record.unpushedQty > 0) {
  312. return (
  313. <div>
  314. <a-input-number
  315. id={'dispacth-cancelNums-' + record.productSn}
  316. size="small"
  317. value={record.cancelNums}
  318. onChange={e => _this.cancelNumsChange(e, record)}
  319. precision={0}
  320. min={0}
  321. max={record.unpushedQty}
  322. style="width: 100%;"
  323. placeholder="请输入" />
  324. </div>
  325. )
  326. }
  327. return '--'
  328. }
  329. // 转采购额数量输入框
  330. const inputFormat1 = function (record, data, h) {
  331. if (record.unpushedQty >= 0 && record.convertPromoGiftsFlag) {
  332. // 已选
  333. if (_this.selectedRowKeys.includes(record.id)) {
  334. return (
  335. <div>
  336. <a-input-number
  337. id={'dispacth-maxConvertNums-' + record.productSn}
  338. size="small"
  339. value={record.convertPromoGiftsQty}
  340. onChange={e => _this.convertPromoGiftsChange(e, record)}
  341. precision={0}
  342. min={0}
  343. max={record.maxConvertNums}
  344. style="width: 100%;"
  345. placeholder="请输入" />
  346. </div>
  347. )
  348. } else {
  349. return record.convertPromoGiftsQty || 0
  350. }
  351. }
  352. return '--'
  353. }
  354. // 操作按钮
  355. const actionFormat = function (record, data, h) {
  356. if (record.unpushedQty > 0) {
  357. return (
  358. <div>
  359. <a-button
  360. id={'dispacth-handleAdd-' + record.productSn}
  361. size="small"
  362. type="link"
  363. class="button-info"
  364. onClick={() => _this.handleAdd(record)}
  365. >添加</a-button>
  366. </div>
  367. )
  368. }
  369. return '--'
  370. }
  371. // 编号,并且格式化活动分类行
  372. const noFormat = function (record, data, h) {
  373. const isBuyPSendP = record.promo && record.promo.promotionRule.convertExpenseFlag == 1 && record.promo.promotionRule.promotionRuleType == 'BUY_PROD_GIVE_PROD'
  374. return (
  375. <div>
  376. {record.id.indexOf('promo-') >= 0 ? (
  377. <div class="active-title">
  378. {record.promo ? (
  379. <div>
  380. <strong style="font-size:14px;">{record.promo.promotion.description} </strong>
  381. <span>({record.promo.promotionRule.description})</span>
  382. <span id={'dispacth-desc-' + record.promo.promoRuleSn} style="margin-left:20px;color:#00aaff;cursor: pointer;" onClick={() => _this.showDesc(record.promo)}>
  383. <a-icon title="查看活动详情" type="eye"/> 活动详情
  384. </span>
  385. </div>
  386. ) : (<div></div>)}
  387. <div>
  388. 款数:<strong>{record.total && record.total.totalCategory || '--'}</strong>;
  389. 数量:<strong>{record.total && record.total.totalQty || '--'}</strong>;
  390. {_this.$hasPermissions('B_salesEdit_salesPrice') ? (<span>总金额:<strong>{record.total && record.total.totalAmount || '--'}</strong>;</span>) : ('')}
  391. {_this.$hasPermissions('B_salesEdit_salesPrice') && record.promo && record.total && record.total.lossAmount ? (<span>优惠金额:<strong>{record.total.lossAmount}</strong>;</span>) : ('')}
  392. {_this.$hasPermissions('B_salesEdit_salesPrice') && record.promo && record.total && record.total.cgejyAmount > 0 && !isBuyPSendP ? (<span>采购额结余:<strong>{_this.toThousands(record.total.cgejyAmount)}</strong>;</span>) : ('')}
  393. {_this.$hasPermissions('B_salesEdit_salesPrice') && record.promo && record.total && record.total.cgejyAmount < 0 && !isBuyPSendP ? (<span>采购额超出:<strong>{_this.toThousands(record.total.cgeccAmount)}</strong>;</span>) : ('')}
  394. {_this.$hasPermissions('B_salesEdit_salesPrice') && record.promo && record.total && record.total.totalPromoGiftsAmount && isBuyPSendP ? (<span>促销产品转采购额金额:<strong>{_this.toThousands(record.total && record.total.totalPromoGiftsAmount) || '--'}</strong>;</span>) : ('')}
  395. {record.expenseAccountFlag != 'WAIT' ? record.expenseAccountFlagDictValue : ''}
  396. </div>
  397. </div>
  398. ) : (<span>{data}</span>)}
  399. </div>
  400. )
  401. }
  402. let arr = [
  403. { title: '', field: '', key: 'acheck', width: 50, type: 'checkbox', align: 'center' },
  404. { title: '序号', field: 'no', key: 'a', width: 50, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return noFormat(row, row[column.field], h) } },
  405. { title: '产品编码', field: 'productCode', key: 'b', width: 150, align: 'left', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return codeFormat(row, row[column.field], h) } },
  406. { title: '产品名称', field: 'productName', key: 'c', width: 250, align: 'left', operationColumn: false, ellipsis: { showTitle: true }, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  407. { title: '原厂编码', field: 'productOrigCode', key: 'd', width: 150, align: 'left', operationColumn: false, ellipsis: { showTitle: true }, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  408. { title: '出库仓库', field: 'warehouseName', key: 'e', width: 100, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } }
  409. ]
  410. this.colspanNums = this.showConvertPromoGifts ? 7 : 6
  411. if (this.$hasPermissions('B_salesDispatch_salesPrice')) { // 售价权限
  412. this.colspanNums = this.colspanNums + 1
  413. arr.push({ title: '销售价', field: 'price', width: 80, key: 'f', align: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return priceFormat(row, row[column.field], h) } })
  414. }
  415. if (this.$hasPermissions('B_salesDispatch_costPrice')) { // 成本价权限
  416. this.colspanNums = this.colspanNums + 1
  417. arr.push({ title: '成本价', field: 'showCost', width: 80, key: 'g', align: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return _this.toThousands(row[column.field]) || '--' } })
  418. }
  419. this.colspanNums = this.colspanNums + 8
  420. arr = arr.concat([
  421. { title: '单位', field: 'productOrigUnit', key: 'i', width: 80, align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return row[column.field] || '--' } },
  422. { title: '可用库存', field: 'stockQty', width: 80, key: 'j', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } }
  423. ])
  424. if (this.showLockStockQty) {
  425. arr.push({ title: '锁定库存', field: 'lockStockQty', width: 80, key: 'jk', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } })
  426. }
  427. arr = arr.concat([
  428. { title: '销售数量', field: 'qty', width: 80, key: 'k', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  429. { title: '已取消', field: 'cancelQty', width: 80, key: 'o', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  430. { title: '已下推', field: 'pushedQty', width: 80, key: 'p', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  431. { title: '待下推', field: 'unpushedQty', width: 80, key: 'q', align: 'center', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return numsFormat(row[column.field]) } },
  432. { title: '取消数量', field: 'cancelNums', width: 80, key: 'r', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return inputFormat(row, row[column.field], h) } }
  433. ])
  434. // 是否显示转采购额
  435. if (this.showConvertPromoGifts) {
  436. arr.push({ title: '转采购额数量',
  437. field: 'convertPromoGiftsQty',
  438. width: 80,
  439. key: 'z',
  440. align: 'center',
  441. fixed: 'right',
  442. operationColumn: false,
  443. renderBodyCell: ({ row, column, rowIndex }, h) => {
  444. return inputFormat1(row, row[column.field], h)
  445. } })
  446. }
  447. arr.push({ title: '操作', field: 'action', width: 80, key: 's', align: 'center', fixed: 'right', operationColumn: false, renderBodyCell: ({ row, column, rowIndex }, h) => { return actionFormat(row, row[column.field], h) } })
  448. return arr
  449. }
  450. },
  451. methods: {
  452. // 查看活动详情
  453. showDesc (row) {
  454. this.detailSn = row.promoRuleSn
  455. this.openDetailModal = true
  456. },
  457. // 关闭详情弹窗
  458. closeDetailModal () {
  459. this.detailSn = null
  460. this.openDetailModal = false
  461. },
  462. // 合并活动分类单元格
  463. bodyCellSpan ({ row, column, rowIndex }) {
  464. if (row.id.indexOf('promo-') >= 0) {
  465. if (column.field == 'no') {
  466. return {
  467. rowspan: 1,
  468. colspan: this.colspanNums
  469. }
  470. } else {
  471. return {
  472. rowspan: 0,
  473. colspan: 0
  474. }
  475. }
  476. }
  477. },
  478. // 取消数量变更
  479. cancelNumsChange (v, record) {
  480. record.cancelNums = v
  481. this.dataSource.splice()
  482. },
  483. // 转采购数量变更
  484. convertPromoGiftsChange (v, record) {
  485. record.convertPromoGiftsQty = v
  486. this.dataSource.splice()
  487. },
  488. // 选择单元格
  489. selectedRowChange ({ row, isSelected, selectedRowKeys }) {
  490. // console.log(row, isSelected, selectedRowKeys);
  491. this.selectedRowKeys = selectedRowKeys
  492. if (!isSelected) {
  493. row.convertPromoGiftsQty = row.bakConvertPromoGiftsQty
  494. }
  495. },
  496. // 全选行
  497. selectedAllChange ({ isSelected, selectedRowKeys }) {
  498. this.selectedRowKeys = selectedRowKeys
  499. // 取消全选后,重置数量
  500. if (!isSelected && this.showConvertPromoGifts) {
  501. this.dataSource.filter(item => item.convertPromoGiftsQty).map(item => {
  502. item.convertPromoGiftsQty = item.bakConvertPromoGiftsQty
  503. })
  504. }
  505. },
  506. // 获取销售单参与的活动列表
  507. getActiveList () {
  508. salesPromoQueryList({ salesBillSn: this.salesBillSn }).then(res => {
  509. if (res.status == 200) {
  510. this.activeList = res.data.filter(item => item.enabledFlag == 1) || []
  511. }
  512. this.$nextTick(() => {
  513. this.searchTable()
  514. })
  515. })
  516. },
  517. // 查询列表
  518. async searchTable () {
  519. this.selectedRowKeys = []
  520. this.disableSelectedRowKeys = []
  521. this.dataSource = []
  522. this.disabled = true
  523. this.spinning = true
  524. this.queryParam.salesBillSn = this.salesBillSn
  525. this.queryParam.showStock = true
  526. const params = this.queryParam
  527. // 获取活动列表
  528. const active = this.activeList
  529. // 正常产品
  530. const hasSearchNormal = !params.promotionFlag || params.promotionFlag == 0
  531. const proList = hasSearchNormal ? await salesDetailAllList(params).then(res => res.data) : []
  532. const norTotal = hasSearchNormal ? await salesDetaiCount(params).then(res => res.data) : null
  533. // 是否有正常产品
  534. this.hasNormalProduct = proList.length > 0
  535. // 没有活动时不显示统计
  536. let listData = active.length ? (proList.length ? [{
  537. id: 'promo-normal',
  538. total: norTotal
  539. }, ...proList] : []) : proList
  540. if (params.promotionFlag != 0) {
  541. // 循环获取活动产品
  542. for (let i = 0; i < active.length; i++) {
  543. const promo = active[i]
  544. const activeParams = {
  545. promoRuleSn: promo.promoRuleSn,
  546. promoSn: promo.promoSn,
  547. salesPromoSn: promo.salesPromoSn,
  548. ...params
  549. }
  550. // 获取活动产品统计
  551. const acTotal = await salesPromoDetailCount(activeParams).then(res => res.data)
  552. if (acTotal) {
  553. // 采购额结余
  554. acTotal.cgejyAmount = (Number(acTotal.totalPromoGiftsAmount || 0) - Number(acTotal.totalUsePromoGiftsAmount || 0)).toFixed(2)
  555. // 采购额超出
  556. acTotal.cgeccAmount = (Number(acTotal.totalUsePromoGiftsAmount || 0) - Number(acTotal.totalPromoGiftsAmount || 0)).toFixed(2)
  557. }
  558. // 有数据时才调用接口,避免做无用的调用
  559. if (acTotal && acTotal.totalQty) {
  560. // 获取活动产品列表
  561. const aclist = await salesDetailAllList(activeParams).then(res => res.data)
  562. const retList = aclist.length ? [{
  563. id: 'promo-' + i,
  564. promo: promo,
  565. total: acTotal
  566. }, ...aclist] : []
  567. // 将活动产品数据拼接
  568. listData = aclist && aclist.length ? listData.concat(retList) : listData
  569. }
  570. }
  571. // 如果活动没有任何产品
  572. if (active.length) {
  573. const hasAcp = listData.filter(item => item.id != 'promo-normal').filter(item => item.id.indexOf('promo-') >= 0)
  574. if (hasAcp && hasAcp.length == 0) {
  575. listData = listData.filter(item => item.id.indexOf('promo-') < 0) || []
  576. }
  577. }
  578. }
  579. this.dataSource = listData
  580. // 格式化数据
  581. let f = 0
  582. this.dataSource.map((item, i) => {
  583. const isTjRow = item.id.indexOf('promo-') >= 0
  584. if (isTjRow) { f = f - 1 }
  585. item.no = i + 1 + f
  586. const productCode = (item.productEntity && item.productEntity.code) || (item.dealerProductEntity && item.dealerProductEntity.code)
  587. const productName = (item.productEntity && item.productEntity.name) || (item.dealerProductEntity && item.dealerProductEntity.name)
  588. const productOrigCode = (item.productEntity && item.productEntity.origCode) || (item.dealerProductEntity && item.dealerProductEntity.origCode)
  589. const productOrigUnit = (item.productEntity && item.productEntity.unit) || (item.dealerProductEntity && item.dealerProductEntity.unit)
  590. item.productCode = productCode || '--'
  591. item.productName = productName || '--'
  592. item.productOrigCode = productOrigCode == ' ' ? '--' : productOrigCode
  593. item.productOrigUnit = productOrigUnit || '--'
  594. item.cancelNums = item.unpushedQty
  595. if (item.convertPromoGiftsFlag == 1) {
  596. item.maxConvertNums = item.unpushedQty + item.convertPromoGiftsQty
  597. } else {
  598. item.maxConvertNums = 0
  599. }
  600. // 转采购额数量
  601. item.bakConvertPromoGiftsQty = item.convertPromoGiftsQty
  602. // 库存为0或待下推数为0,不可添加
  603. if (!item.convertPromoGiftsQty && (!item.unpushedQty || item.unpushedQty < 0) || isTjRow) {
  604. this.disableSelectedRowKeys.push(item.id)
  605. }
  606. })
  607. this.showEmpty = this.dataSource.length <= 0
  608. this.tableData = this.dataSource
  609. this.spinning = false
  610. this.disabled = false
  611. },
  612. // 重置
  613. resetSearchForm (detailData) {
  614. this.queryParam.pushProductType = ''
  615. this.queryParam.productCode = ''
  616. this.queryParam.productName = ''
  617. this.queryParam.promotionFlag = undefined
  618. this.queryParam.brandSn = undefined
  619. this.queryParam.productTypeSn1 = ''
  620. this.queryParam.productTypeSn2 = ''
  621. this.queryParam.productTypeSn3 = ''
  622. this.queryParam.warehouseSn = undefined
  623. this.queryParam.convertPromoGiftsFlag = undefined
  624. this.productType = []
  625. this.dataSource = []
  626. this.clearSelectTable()
  627. this.searchTable()
  628. if (detailData) {
  629. this.detailData = detailData
  630. }
  631. },
  632. pageInit (salesBillSn, detailData) {
  633. this.salesBillSn = salesBillSn
  634. this.detailData = detailData
  635. // 获取活动列表
  636. this.getActiveList()
  637. // 是否转过采购单
  638. this.hasCreatePurchaseFlag()
  639. },
  640. // 清空选项
  641. clearSelectTable () {
  642. this.selectedRowKeys = []
  643. },
  644. // 添加
  645. handleAdd (row) {
  646. if (row.stockQty > 0) { // 可用库存大于0才可添加
  647. this.$emit('addProduct', [row.salesBillDetailSn])
  648. } else {
  649. if (row && row.productEntity && row.productEntity.productBrandName == '箭冠' && row.productEntity.productTypeName3 == '轮胎') {
  650. this.$message.warning('锁定库存不足!')
  651. } else {
  652. this.$message.warning('库存为0,不可添加!')
  653. }
  654. }
  655. },
  656. // 批量转采购额
  657. handlePlPurchase () {
  658. const _this = this
  659. const chooseList = this.selectedRowKeys
  660. if (chooseList.length == 0) {
  661. _this.$message.warning('请先选择产品!')
  662. return
  663. }
  664. const chooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.convertPromoGiftsFlag == 1)
  665. const noChooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && !item.convertPromoGiftsFlag)
  666. const obj = []
  667. const noObj = []
  668. noChooseRow && noChooseRow.map(item => {
  669. noObj.push(item.productCode)
  670. })
  671. chooseRow && chooseRow.map(item => {
  672. obj.push({
  673. 'convertPromoGiftsQty': item.convertPromoGiftsQty,
  674. 'salesBillDetailSn': item.salesBillDetailSn
  675. })
  676. })
  677. if (obj.length) {
  678. this.$confirm({
  679. title: '提示',
  680. content: <div><div style="text-align:center;padding:10px 0;font-weight:bold;">确定将选中的促销产品转成采购额吗?</div>{noObj.length ? <div style="text-align:center;"><div>总共选择了 {chooseList.length} 个产品,其中 {obj.length} 个产品可转采购额。</div><div style="color:red;"> 产品 ({noObj.toString()}) 不可转采购额!</div></div> : ''}<div style="font-size:12px;color:#999;padding:10px 0;text-align:center;">
  681. 当该销售单完结后,可将采购额转成费用报销单。</div></div>,
  682. centered: true,
  683. closable: true,
  684. class: 'confirm-center',
  685. onOk () {
  686. _this.$emit('convertPromoGifts', obj)
  687. }
  688. })
  689. } else {
  690. _this.$message.warning('所选产品都不可转采购额!')
  691. }
  692. },
  693. // 批量添加
  694. handlePlAdd () {
  695. const _this = this
  696. const chooseList = this.selectedRowKeys
  697. if (chooseList.length == 0) {
  698. _this.$message.warning('请先选择产品!')
  699. return
  700. }
  701. // 可添加产品
  702. const chooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.stockQty > 0)
  703. // 库存为0的产品
  704. const noStockRow = this.dataSource.filter(item => chooseList.includes(item.id) && !item.stockQty)
  705. // 冻结库存为0的产品
  706. const noLockStockRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.productEntity && item.productEntity.productBrandName == '箭冠' && item.productEntity.productTypeName3 == '轮胎' && !item.lockStockQty)
  707. // 可添加产品sn列表
  708. const obj = []
  709. chooseRow && chooseRow.map(item => {
  710. obj.push(item.salesBillDetailSn)
  711. })
  712. // 库存为0产品编码列表
  713. const noObj = []
  714. noStockRow && noStockRow.map(item => {
  715. noObj.push(item.productCode)
  716. })
  717. // 冻结库存为0的产品
  718. const noLockObj = []
  719. noLockStockRow && noLockStockRow.map(item => {
  720. noLockObj.push(item.productCode)
  721. })
  722. if (obj.length) {
  723. this.$confirm({
  724. title: '提示',
  725. content: <div><div style="text-align:center;padding:10px 0;font-weight:bold;">确认要批量添加到待下推列表吗?</div>{(noObj.length || noLockObj.length) ? <div><div>总共选择了 {chooseList.length} 个产品,其中 {obj.length} 个产品可添加。</div><div> {noObj.length ? <div>产品 ({noObj.toString()}) 因库存为0不可添加!</div> : noLockObj.length ? <div>产品 ({noLockObj.toString()}) 因锁定库存不足不可添加!</div> : ''}</div></div> : ''}</div>,
  726. centered: true,
  727. closable: true,
  728. class: 'confirm-center',
  729. onOk () {
  730. _this.$emit('addProduct', obj)
  731. }
  732. })
  733. } else {
  734. _this.$message.warning('所选产品库存都为0,不可添加!')
  735. }
  736. },
  737. // 整单取消
  738. handleAllCancel () {
  739. const _this = this
  740. this.$confirm({
  741. title: '提示',
  742. content: '确定整单取消订单?',
  743. centered: true,
  744. closable: true,
  745. onOk () {
  746. _this.$emit('cancelAll')
  747. }
  748. })
  749. },
  750. // 批量取消
  751. handlePlCancel () {
  752. const _this = this
  753. const chooseList = this.selectedRowKeys
  754. if (chooseList.length == 0) {
  755. _this.$message.warning('请先选择产品!')
  756. return
  757. }
  758. const chooseRow = this.dataSource.filter(item => chooseList.includes(item.id) && item.id.indexOf('promo-') < 0)
  759. const hasActive = chooseRow && chooseRow.filter(item => item.promotionFlag != 0)
  760. if (hasActive.length > 0) {
  761. _this.$message.warning('参与促销的产品只可进行整单取消!')
  762. return
  763. }
  764. const obj = []
  765. chooseRow && chooseRow.map(item => {
  766. obj.push({
  767. 'cancelQty': item.cancelNums,
  768. 'salesBillDetailSn': item.salesBillDetailSn
  769. })
  770. })
  771. this.$emit('cancelProduct', obj)
  772. },
  773. // 确认整单转采购单
  774. confirPurchaseModal () {
  775. this.loading = true
  776. getCreatePurchaseFlag({ salesBillSn: this.salesBillSn }).then(res => {
  777. if (res.status == '200') {
  778. // 没有转过
  779. if (res.data == 0) {
  780. this.showPurchaseModal()
  781. } else {
  782. // 转过,弹确认框
  783. const _this = this
  784. this.$confirm({
  785. title: '提示',
  786. content: '已转过采购单,是否再次转单?',
  787. centered: true,
  788. closable: true,
  789. onOk () {
  790. _this.showPurchaseModal()
  791. }
  792. })
  793. }
  794. }
  795. this.loading = false
  796. })
  797. },
  798. // 打开转采购单弹框
  799. showPurchaseModal () {
  800. this.openPurchaseModal = true
  801. this.$refs.purchaseModal.setDetail(this.detailData)
  802. },
  803. // 是否转过采购单
  804. hasCreatePurchaseFlag () {
  805. getCreatePurchaseFlag({ salesBillSn: this.salesBillSn }).then(res => {
  806. this.showLockStockQty = res.data && res.data == 1
  807. })
  808. }
  809. }
  810. }
  811. </script>
  812. <style lang="less">
  813. .empty-data{
  814. color: #999;
  815. text-align: center;
  816. padding: 20px;
  817. }
  818. .ve-table-body-td{
  819. .active-title{
  820. display: flex;
  821. align-items: center;
  822. justify-content: space-between;
  823. padding: 10px;
  824. background: #f3f8fa;
  825. }
  826. }
  827. .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-body-tr td.table-body-cell-no,
  828. .ve-table .ve-table-container .ve-table-content-wrapper table.ve-table-content tbody.ve-table-body tr.ve-table-expand-tr td.table-body-cell-no{
  829. padding: 0;
  830. }
  831. .ve-table .ve-table-container .ve-table-content-wrapper{
  832. border-bottom: 1px solid #ddd;
  833. }
  834. </style>