salesToProduction.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never">
  4. <div class="body-title">
  5. <div class="title-left">销售订单转生产计划</div>
  6. <div class="title-right">
  7. <el-button @click="cancel">取消</el-button>
  8. <el-button type="primary" @click="toSubmit" :loading="loading">
  9. 提交计划
  10. </el-button>
  11. </div>
  12. </div>
  13. <el-form ref="form" :model="form" :rules="rules" label-width="90px" class="formbox">
  14. <el-row :gutter="24">
  15. <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
  16. <el-form-item label="计划类型:">
  17. <DictSelection dictName="订单计划类型" clearable v-model="form.planType">
  18. </DictSelection>
  19. </el-form-item>
  20. </el-col>
  21. <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
  22. <el-form-item label="生产版本:" prop="producteVersionName">
  23. <el-input @click.native="openVersion" placeholder="请选择生产版本" readonly v-model="form.producteVersionName"></el-input>
  24. </el-form-item>
  25. </el-col>
  26. <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
  27. <el-form-item label="产线:">
  28. <el-input v-model="form.productline" placeholder="选择生产版本带入" readonly></el-input>
  29. </el-form-item>
  30. </el-col>
  31. <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
  32. <el-form-item label="使用改型:" prop="modification">
  33. <el-checkbox v-model="form.modification" :true-label='1' :false-label='0'></el-checkbox>
  34. </el-form-item>
  35. </el-col>
  36. </el-row>
  37. <el-row :gutter="24" class="row-intro">
  38. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  39. <el-form-item label="销售单数量:">{{form.codeNum}}</el-form-item>
  40. </el-col>
  41. <el-col v-bind="styleResponsive ? { lg: 4, md: 12 } : { span: 4 }">
  42. <el-form-item label="订单总数量:">{{form.contractNum}}</el-form-item>
  43. </el-col>
  44. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  45. <el-form-item label="订单总重量:">{{form.sumOrderWeight}}</el-form-item>
  46. </el-col>
  47. <el-col v-bind="styleResponsive ? { lg: 5, md: 12 } : { span: 5 }">
  48. <el-form-item label="产品编码:">{{form.productCode}}</el-form-item>
  49. </el-col>
  50. <el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
  51. <el-form-item label="牌号|型号:">{{form.brandNo}}|{{form.model}}</el-form-item>
  52. </el-col>
  53. <el-col v-bind="styleResponsive ? { lg: 3, md: 12 } : { span: 3 }">
  54. <el-form-item label="库存数量:">{{form.stockCountBase}}</el-form-item>
  55. </el-col>
  56. </el-row>
  57. <el-table
  58. :data="form.salesOrders"
  59. border
  60. >
  61. <el-table-column label="序号" align="center" width="60">
  62. <template slot-scope="scope">
  63. <span>{{ scope.$index + 1 }}</span>
  64. </template>
  65. </el-table-column>
  66. <el-table-column label="销售订单号" align="center" prop="code" width="120">
  67. </el-table-column>
  68. <el-table-column label="行号" align="center" prop="lineNumber">
  69. </el-table-column>
  70. <el-table-column label="合同数量" align="center" prop="contractNum">
  71. </el-table-column>
  72. <el-table-column label="合同重量" align="center" prop="productSumWeight">
  73. </el-table-column>
  74. <el-table-column label="欠交数量" align="center" prop="lackNum">
  75. </el-table-column>
  76. <el-table-column label="计划生产数" align="center" prop="productNum" width="120">
  77. <template slot-scope="scope">
  78. <el-form-item
  79. label-width="0px"
  80. :prop="'salesOrders.'+ scope.$index + '.productNum'"
  81. :rules="{
  82. required: true,
  83. message: '请输入计划生产数',
  84. trigger: 'blur'
  85. }"
  86. class="table-item"
  87. >
  88. <el-input
  89. v-model.number="scope.row.productNum"
  90. size="small"
  91. oninput="value=value.replace(/[^\d]/g,'')"
  92. style="width: 100%"
  93. placeholder="输入数量"
  94. ></el-input>
  95. </el-form-item>
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="要求成型数量" align="center" prop="requiredFormingNum" width="120">
  99. <template slot-scope="scope">
  100. <el-form-item
  101. label-width="0px"
  102. :prop="'salesOrders.'+ scope.$index + '.requiredFormingNum'"
  103. :rules="{
  104. required: true,
  105. message: '请输入要求成型数量',
  106. trigger: 'blur'
  107. }"
  108. class="table-item"
  109. >
  110. <el-input
  111. v-model.number="scope.row.requiredFormingNum"
  112. size="small"
  113. oninput="value=value.replace(/[^\d]/g,'')"
  114. style="width: 100%"
  115. placeholder="输入数量"
  116. ></el-input>
  117. </el-form-item>
  118. </template>
  119. </el-table-column>
  120. <el-table-column label="按单按库" align="center" prop="orderLibraryType">
  121. <template slot-scope="{row}">
  122. {{getDictValue('按单按库', row.orderLibraryType)}}
  123. </template>
  124. </el-table-column>
  125. <el-table-column label="订单类型" align="center" prop="orderType">
  126. <template slot-scope="{row}">
  127. {{getDictValue('订单类型', row.orderType)}}
  128. </template>
  129. </el-table-column>
  130. <el-table-column label="交付日期" align="center" prop="deliveryTime" width="160">
  131. </el-table-column>
  132. <el-table-column label="要求成型日期" align="center" prop="reqMoldTime" width="180">
  133. <template slot-scope="scope">
  134. <el-form-item
  135. label-width="0px"
  136. :prop="'salesOrders.'+ scope.$index + '.reqMoldTime'"
  137. :rules="{
  138. required: true,
  139. message: '请选择要求成型日期',
  140. trigger: 'blur'
  141. }"
  142. class="table-item"
  143. >
  144. <el-date-picker
  145. style="width: 100%;"
  146. v-model="scope.row.reqMoldTime"
  147. type="date"
  148. placeholder="选择日期"
  149. value-format="yyyy-MM-dd">
  150. </el-date-picker>
  151. <!-- <el-date-picker
  152. style="width: 100%;"
  153. v-model="scope.row.reqMoldTime"
  154. type="datetime"
  155. placeholder="选择日期"
  156. value-format="yyyy-MM-dd HH:mm:ss">
  157. </el-date-picker> -->
  158. </el-form-item>
  159. </template>
  160. </el-table-column>
  161. <el-table-column label="客户名称" align="center" prop="customerName">
  162. </el-table-column>
  163. <el-table-column label="业务员" align="center" prop="salesman">
  164. </el-table-column>
  165. <el-table-column label="交付要求" align="center" prop="deliveryRequirements">
  166. <template slot-scope="{row}">
  167. {{getDictValue('交付要求', row.deliveryRequirements)}}
  168. </template>
  169. </el-table-column>
  170. <el-table-column prop="priority" label="优先级" width="100" align="center">
  171. <template slot-scope="{ row }">
  172. <div class="sort-wrap">
  173. <i class="el-icon-caret-top" @click="sortTop(row)"></i>
  174. <i class="el-icon-caret-bottom" @click="sortBottom(row)"></i>
  175. </div>
  176. </template>
  177. </el-table-column>
  178. <el-table-column label="操作" align="center" width="70" fixed="right">
  179. <template slot-scope="scope">
  180. <el-button
  181. type="text"
  182. @click="handleDeleteItem(scope.$index)"
  183. >删除</el-button
  184. >
  185. </template>
  186. </el-table-column>
  187. </el-table>
  188. <div class="add-product" @click='addEquipment'>
  189. <i class="el-icon-circle-plus-outline"></i>
  190. </div>
  191. <el-row :gutter="24">
  192. <el-col v-bind="styleResponsive ? { lg: 24, md: 24 } : { span: 24 }">
  193. <el-form-item label="计划备注:">
  194. <el-input type="textarea" :rows="4" v-model="form.notes" resize='none'></el-input>
  195. </el-form-item>
  196. </el-col>
  197. </el-row>
  198. </el-form>
  199. <AdditionalOrder ref="additionalRefs" :productCode="form.productCode" :selectList="form.salesOrders" @choose="confirmChoose"></AdditionalOrder>
  200. <ProductionVersion ref="versionRefs" @confirm="confirmVersion" :productCode="form.productCode"></ProductionVersion>
  201. <PlanSubmit ref="submitRefs" :info="form" @publish="publishData"></PlanSubmit>
  202. </el-card>
  203. </div>
  204. </template>
  205. <script>
  206. import AdditionalOrder from './components/AdditionalOrder.vue';
  207. import PlanSubmit from './components/plan-submit.vue';
  208. import ProductionVersion from '@/components/CreatePlan/ProductionVersion.vue'
  209. import { productionToPlan , saveSaleToPlan } from '@/api/saleOrder';
  210. import dictMixins from '@/mixins/dictMixins';
  211. import { deepClone } from '@/utils/index';
  212. import { finishPageTab , reloadPageTab } from '@/utils/page-tab-util';
  213. export default {
  214. mixins: [dictMixins],
  215. components: {
  216. AdditionalOrder,
  217. ProductionVersion,
  218. PlanSubmit
  219. },
  220. data () {
  221. return {
  222. form:{
  223. producteVersionId:'',
  224. salesOrders:[]
  225. },
  226. // 表单验证规则
  227. rules: {
  228. producteVersionName:[{required: true,message: '请选择生产版本',trigger: 'change'}]
  229. },
  230. selection:[],
  231. loading:false
  232. };
  233. },
  234. computed: {
  235. // 是否开启响应式布局
  236. styleResponsive() {
  237. return this.$store.state.theme.styleResponsive;
  238. }
  239. },
  240. created() {
  241. this.requestDict('按单按库');
  242. this.requestDict('订单类型');
  243. this.requestDict('交付要求');
  244. this.selection = JSON.parse(this.$route.query.selection)
  245. const list = []
  246. this.selection.map(item=>{
  247. list.push(item.id)
  248. })
  249. this.getSaleInfo(list)
  250. },
  251. methods: {
  252. getSaleInfo(params){
  253. productionToPlan(params).then(res=>{
  254. this.form = deepClone(res)
  255. this.form.salesOrders.map((item,index)=>{
  256. item.priority = index+1
  257. })
  258. })
  259. },
  260. cancel(){
  261. this.$router.go(-1)
  262. },
  263. toSubmit(){
  264. this.$refs.form.validate((valid) => {
  265. if (valid) {
  266. this.mapList()
  267. this.$refs.submitRefs.open()
  268. }
  269. });
  270. },
  271. // 对比日期,计算要求成型重量
  272. mapList(){
  273. var requiredFormingWeight = 0
  274. var requiredFormingNum = 0
  275. this.form.salesOrders.map((item,index)=>{
  276. requiredFormingWeight = requiredFormingWeight + Number(item.productUnitWeight) * Number(item.requiredFormingNum)
  277. requiredFormingNum = requiredFormingNum + item.requiredFormingNum
  278. })
  279. this.form.requiredFormingWeight = requiredFormingWeight.toFixed(2)
  280. this.form.requiredFormingNum = requiredFormingNum
  281. const collection = deepClone(this.form.salesOrders)
  282. const sortedCollection = collection.sort((a, b) => new Date(b.reqMoldTime) - new Date(a.reqMoldTime));
  283. let latestData = {};
  284. for (let i = 0; i < sortedCollection.length; i++) {
  285. const data = sortedCollection[i];
  286. if (!latestData.reqMoldTime || new Date(data.reqMoldTime) >= new Date(latestData.reqMoldTime)) {
  287. latestData = data;
  288. }
  289. }
  290. this.form.reqMoldTime = latestData.reqMoldTime
  291. },
  292. sortTop (row) {
  293. if (row.priority <= 1) {
  294. return;
  295. }
  296. let rowN = this.form.salesOrders.find((n) => n.priority == row.priority - 1);
  297. rowN.priority += 1;
  298. row.priority -= 1;
  299. this.form.salesOrders.sort((a, b) => {
  300. return a.priority - b.priority;
  301. });
  302. },
  303. sortBottom (row) {
  304. if (row.priority >= this.form.salesOrders.length) {
  305. return;
  306. }
  307. let rowN = this.form.salesOrders.find((n) => n.priority == row.priority + 1);
  308. rowN.priority -= 1;
  309. row.priority += 1;
  310. this.form.salesOrders.sort((a, b) => {
  311. return a.priority - b.priority;
  312. });
  313. },
  314. againSort () {
  315. this.form.salesOrders.forEach((n, index) => {
  316. n.priority = index + 1;
  317. });
  318. },
  319. // 删除产品
  320. handleDeleteItem (index) {
  321. this.form.salesOrders.splice(index, 1)
  322. },
  323. addEquipment(){
  324. this.$refs.additionalRefs.open()
  325. },
  326. openVersion(){
  327. this.$refs.versionRefs.open()
  328. },
  329. confirmVersion(data){
  330. this.$set(this.form,'producteVersionName',data.produceVersionName)
  331. this.$set(this.form,'producteVersionId',data.produceVersionId)
  332. this.form.productline = data.lineNames.length?data.lineNames[0]:''
  333. },
  334. confirmChoose(list){
  335. // 取出在弹窗中选中并且不在表格中的数据
  336. const result = list.filter(
  337. i => this.form.salesOrders.findIndex(p => p.id === i.id) === -1
  338. )
  339. // 取出在表格中并且不在弹窗中选中的数据 即取消选中的数据
  340. const del = this.form.salesOrders.filter(
  341. i => list.findIndex(p => p.id === i.id) === -1
  342. )
  343. for(let i= this.form.salesOrders.length-1;i>=0;i--){
  344. for(let j in del){
  345. if(this.form.salesOrders[i].id === del[j].id){
  346. this.form.salesOrders.splice(i,1);
  347. }
  348. }
  349. }
  350. this.form.salesOrders = this.form.salesOrders.concat(result)
  351. this.changeData()
  352. },
  353. changeData(){
  354. var productNum = 0
  355. var productWeight = 0
  356. this.form.salesOrders.map((item,index)=>{
  357. item.priority = index+1
  358. productNum = productNum + item.contractNum
  359. productWeight = productWeight + Number(item.productSumWeight)
  360. })
  361. this.$set(this.form,'codeNum',this.form.salesOrders.length)
  362. this.$set(this.form,'contractNum',productNum)
  363. this.$set(this.form,'sumOrderWeight',productWeight.toFixed(2))
  364. },
  365. publishData(type){
  366. console.log('type',type)
  367. let params = deepClone(this.form)
  368. delete params.id
  369. saveSaleToPlan(params).then(res=>{
  370. finishPageTab()
  371. reloadPageTab({ fullPath: '/saleOrder' });
  372. this.$router.go(-1)
  373. })
  374. }
  375. }
  376. };
  377. </script>
  378. <style lang="scss" scoped>
  379. .ele-body{
  380. background: #fff;
  381. }
  382. .body-title{
  383. width: 100%;
  384. display: flex;
  385. align-items: center;
  386. justify-content: space-between;
  387. }
  388. .title-left{
  389. font-size: 20px;
  390. color: #333;
  391. }
  392. .formbox{
  393. margin: 20px auto;
  394. }
  395. .row-intro{
  396. border-bottom: 1px dashed #ccc;
  397. margin-bottom: 20px;
  398. }
  399. .sort-wrap {
  400. i {
  401. font-size: 30px;
  402. cursor: pointer;
  403. }
  404. .el-icon-caret-top {
  405. color: red;
  406. }
  407. .el-icon-caret-bottom {
  408. color: #157a2c;
  409. }
  410. }
  411. .add-product{
  412. width:100%;
  413. display:flex;
  414. align-items:center;
  415. justify-content:flex-end;
  416. font-size:30px;
  417. color:#1890ff;
  418. margin:10px 0;
  419. cursor: pointer;
  420. }
  421. .table-item{
  422. margin-bottom: 0;
  423. }
  424. </style>