plm前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

741 lines
34 KiB

1 year ago
1 year ago
1 year ago
1 year ago
7 months ago
1 year ago
8 months ago
7 months ago
8 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
7 months ago
7 months ago
1 year ago
1 year ago
9 months ago
8 months ago
1 year ago
10 months ago
1 year ago
10 months ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
8 months ago
1 year ago
7 months ago
9 months ago
1 year ago
8 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
7 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
7 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
7 months ago
1 year ago
1 year ago
1 year ago
9 months ago
7 months ago
9 months ago
1 year ago
1 year ago
9 months ago
1 year ago
1 year ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
7 months ago
1 year ago
  1. <script>
  2. import {queryQuoteDetailAllCost} from "../../../../../api/quote/quoteDetail";
  3. import {Decimal} from "decimal.js";
  4. import DictDataSelect from "../../../sys/dict-data-select.vue";
  5. export default {
  6. name: "quoteDetailCost",
  7. components: {DictDataSelect},
  8. props: {
  9. quoteDetail: {
  10. type: Object,
  11. required: true
  12. },
  13. },
  14. model: {
  15. prop: "quoteDetail",
  16. event: "update",
  17. },
  18. data(){
  19. return {
  20. computeLoading:false,
  21. quoteDetail: {
  22. id: null,
  23. otherCost: null,
  24. elseCost: null,
  25. machineCost: null,
  26. profitAmount: null,
  27. totalPrice: null,
  28. adjustToolCost: null,
  29. adjustLabourCost: null,
  30. currencyTotalCost1: null,
  31. adjustBomUnYield: null,
  32. currencyTotalCost2: null,
  33. toolCost: null,
  34. quoteCurrencyTotalCost1: null,
  35. adjustElseCost: null,
  36. quoteCurrencyTotalCost2: null,
  37. unitPrice: null,
  38. quoteProfitRate: null,
  39. testCost: null,
  40. shippingCost: null,
  41. taxTotalPrice: null,
  42. quoteProfitAmount: null,
  43. adjustFabricateCost: null,
  44. adjustTestCost: null,
  45. profitRate: null,
  46. partCost: null,
  47. calculatedItems: null,
  48. adjustMachineCost: null,
  49. taxUnitPrice: null,
  50. manageCost: null,
  51. taxRate: null,
  52. quoteTaxTotalPrice: null,
  53. labourCost: null,
  54. fabricateCost: null,
  55. currency1: null,
  56. bomUnYield: null,
  57. currency2: null,
  58. exchangeRate1: null,
  59. exchangeRate2: null,
  60. packCost: null,
  61. quoteTaxRate: null,
  62. totalCost: null,
  63. adjustPartCost: null,
  64. status: '',
  65. },
  66. rules:{
  67. adjustPartCost: [
  68. { required: true, message: "请输入材料成本", trigger: ["blur","change"] }
  69. ],
  70. adjustBomUnYield: [
  71. { required: true, message: "请输入实际成本", trigger: ["blur","change"] }
  72. ],
  73. adjustMachineCost: [
  74. { required: true, message: "请输入机器成本", trigger: ["blur","change"] }
  75. ],
  76. adjustFabricateCost: [
  77. { required: true, message: "请输入制造费用成本", trigger: ["blur","change"] }
  78. ],
  79. adjustLabourCost: [
  80. { required: true, message: "请输入人工成本", trigger: ["blur","change"] }
  81. ],
  82. adjustToolCost: [
  83. { required: true, message: "请输入工具成本", trigger: ["blur","change"] }
  84. ],
  85. adjustTestCost: [
  86. { required: true, message: "请输入测试成本", trigger: ["blur","change"] }
  87. ],
  88. adjustElseCost: [
  89. { required: true, message: "请输入其他成本", trigger: ["blur","change"] }
  90. ],
  91. manageCost: [
  92. { required: true, message: "请输入管理成本", trigger: ["blur","change"] }
  93. ],
  94. otherCost: [
  95. { required: true, message: "请输入包装&运输成本", trigger: ["blur","change"] }
  96. ],
  97. profitRate: [
  98. { required: true, message: "请输入利润率", trigger: ["blur","change"] }
  99. ],
  100. quoteProfitRate: [
  101. { required: true, message: "请输入报价利润率", trigger: ["blur","change"] }
  102. ],
  103. taxRate: [
  104. { required: true, message: "请输入税率", trigger: ["blur","change"] }
  105. ],
  106. quoteTaxRate: [
  107. { required: true, message: "请输入报价税率", trigger: ["blur","change"] }
  108. ],
  109. },
  110. showQuoteCost:false,
  111. isShowCost:true,
  112. isShowOtherCost:true,
  113. isShowRatePrice:true,
  114. tagNo:undefined,
  115. type:undefined,
  116. allCheckedLabel:['工具','测试','包装','运输','其他'],
  117. // selectionChecked:[],
  118. checkAll:false,
  119. selection:undefined,
  120. totalPartCost:0,
  121. totalElseCost:0,
  122. editInput:'VA',
  123. }
  124. },
  125. methods:{
  126. computeCurrencyTotalCost(){
  127. // if (this.quoteDetail.exchangeRate1 && this.quoteDetail.exchangeRate1 > 0){
  128. // this.quoteDetail.currencyTotalCost1 = new Decimal(this.quoteDetail.totalCost).div(this.quoteDetail.exchangeRate1).toNumber();
  129. // }
  130. // if (this.quoteDetail.exchangeRate2 && this.quoteDetail.exchangeRate2 > 0){
  131. // this.quoteDetail.currencyTotalCost2 = new Decimal(this.quoteDetail.totalCost).div(this.quoteDetail.exchangeRate2).toNumber();
  132. // }
  133. // 特殊处理
  134. if (this.quoteDetail.exchangeRate2 && this.quoteDetail.exchangeRate2 > 0){
  135. this.quoteDetail.currencyTotalCost2 = new Decimal(this.quoteDetail.taxUnitPrice).div(this.quoteDetail.exchangeRate2).toNumber()
  136. }else {
  137. this.quoteDetail.currencyTotalCost2 = 0
  138. }
  139. },
  140. computeTotalCost(){
  141. // 标准总成本
  142. this.quoteDetail.totalCost =
  143. this.quoteDetail.adjustPartCost +
  144. this.quoteDetail.adjustMachineCost +
  145. this.quoteDetail.adjustLabourCost;
  146. if (this.selectionChecked.includes('其他')){
  147. this.quoteDetail.totalCost += this.quoteDetail.adjustElseCost;
  148. }
  149. if (this.selectionChecked.includes('工具')){
  150. this.quoteDetail.totalCost += this.quoteDetail.adjustToolCost;
  151. }
  152. if (this.selectionChecked.includes('测试')){
  153. this.quoteDetail.totalCost += this.quoteDetail.adjustTestCost;
  154. }
  155. if (this.selectionChecked.includes('包装')){
  156. this.quoteDetail.totalCost += this.quoteDetail.packCost;
  157. }
  158. if (this.selectionChecked.includes('运输')){
  159. this.quoteDetail.totalCost += this.quoteDetail.shippingCost;
  160. }
  161. // this.quoteDetail.totalCost += this.quoteDetail.adjustElseCost;
  162. // this.quoteDetail.totalCost += this.quoteDetail.adjustToolCost;
  163. // this.quoteDetail.totalCost += this.quoteDetail.adjustTestCost;
  164. // this.quoteDetail.totalCost += this.quoteDetail.packCost;
  165. // this.quoteDetail.totalCost += this.quoteDetail.shippingCost;
  166. // if (this.selectionChecked.includes('包装&运输')){
  167. // this.quoteDetail.totalCost += this.quoteDetail.otherCost;
  168. // }
  169. // 计算成本
  170. this.computedTotalPartCost();//计算总物料成本和其他额外成本
  171. this.computeMarkup();// 计算利润
  172. this.computeProfitAmount(); // 计算 CNY
  173. this.computeCurrencyTotalCost();//计算外汇成本
  174. },
  175. computeMarkup(){
  176. let val = 0;
  177. let editInput = this.editInput.toLowerCase();
  178. if (editInput === 'va'){
  179. val = this.quoteDetail.quoteProfitRate
  180. }else if (editInput === 'contribution'){
  181. val = this.quoteDetail.quoteProfitAmount
  182. }else if (editInput === 'margin'){
  183. val = this.quoteDetail.quoteTaxRate
  184. }else if (editInput === 'price'){
  185. val = this.quoteDetail.quoteTaxTotalPrice
  186. }
  187. this.computePriceByRate(val,editInput)
  188. },
  189. computeProfitAmount(){
  190. this.quoteDetail.profitAmount =
  191. this.quoteDetail.totalCost * (this.quoteDetail.profitRate / 100);
  192. this.computeTaxCost();
  193. },
  194. computeTaxCost(){
  195. this.quoteDetail.totalPrice =
  196. this.quoteDetail.totalCost + this.quoteDetail.profitAmount;
  197. this.quoteDetail.unitPrice =
  198. this.quoteDetail.quoteTaxTotalPrice ;
  199. this.quoteDetail.taxTotalPrice =
  200. this.quoteDetail.unitPrice + this.quoteDetail.unitPrice * ((this.quoteDetail.taxRate+this.quoteDetail.exchangeRate1) / 100);
  201. this.quoteDetail.taxUnitPrice =
  202. this.quoteDetail.taxTotalPrice ;
  203. this.computeCurrencyTotalCost();
  204. },
  205. handleQueryAllCost(){
  206. let params = {
  207. ...this.quoteDetail
  208. }
  209. this.computeLoading = true
  210. queryQuoteDetailAllCost(params).then(({data})=>{
  211. if (data && data.code === 0){
  212. this.quoteDetail.partCost = data.row.unitQuotePrice;// 标准成本
  213. this.quoteDetail.adjustPartCost = data.row.unitQuotePrice;
  214. this.quoteDetail.bomUnYield = data.row.actualQuotePrice;//实际成本
  215. this.quoteDetail.adjustBomUnYield = data.row.actualQuotePrice;
  216. this.quoteDetail.labourCost = data.row.labourCost;
  217. this.quoteDetail.adjustLabourCost = data.row.labourCost;
  218. this.quoteDetail.machineCost = data.row.machineCost;
  219. this.quoteDetail.adjustMachineCost = data.row.machineCost;
  220. this.quoteDetail.fabricateCost = data.row.manufactureCost;
  221. this.quoteDetail.adjustFabricateCost = data.row.manufactureCost;
  222. this.quoteDetail.toolCost = data.row.toolCost;
  223. this.quoteDetail.adjustToolCost = data.row.toolCost;
  224. this.quoteDetail.testCost = data.row.testCost;
  225. this.quoteDetail.adjustTestCost = data.row.testCost;
  226. this.quoteDetail.elseCost = data.row.elseCost;
  227. this.quoteDetail.adjustElseCost = data.row.elseCost;
  228. this.quoteDetail.packCost = data.row.packCost;
  229. this.quoteDetail.shippingCost = data.row.shippingCost;
  230. this.quoteDetail.otherCost = data.row.otherCost;
  231. this.computedTotalPartCost();// 重新计算成本
  232. }else {
  233. this.$message.warning(data.msg);
  234. }
  235. this.computeLoading = false
  236. }).catch((error)=>{
  237. this.$message.error(error);
  238. this.computeLoading = false
  239. })
  240. },
  241. changeAllCheck(val){
  242. if (val){
  243. this.selectionChecked = [...this.allCheckedLabel]
  244. }else {
  245. this.selectionChecked = [];
  246. }
  247. },
  248. computedTotalPartCost(){
  249. this.totalPartCost = this.quoteDetail.adjustPartCost;
  250. if (this.selectionChecked.includes('工具')){
  251. this.totalPartCost += this.quoteDetail.adjustToolCost;
  252. }
  253. if (this.selectionChecked.includes('测试')){
  254. this.totalPartCost += this.quoteDetail.adjustTestCost;
  255. }
  256. if (this.selectionChecked.includes('其他')){
  257. this.totalPartCost += this.quoteDetail.adjustElseCost;
  258. }
  259. if (this.selectionChecked.includes('包装')){
  260. this.totalPartCost += this.quoteDetail.packCost;
  261. }
  262. if (this.selectionChecked.includes('运输')){
  263. this.totalPartCost += this.quoteDetail.shippingCost;
  264. }
  265. this.totalElseCost = 0;
  266. if (!this.selectionChecked.includes('工具')){
  267. this.totalElseCost += this.quoteDetail.adjustToolCost;
  268. }
  269. if (!this.selectionChecked.includes('测试')){
  270. this.totalElseCost += this.quoteDetail.adjustTestCost;
  271. }
  272. if (!this.selectionChecked.includes('其他')){
  273. this.totalElseCost += this.quoteDetail.adjustElseCost;
  274. }
  275. if (!this.selectionChecked.includes('包装')){
  276. this.totalElseCost += this.quoteDetail.packCost;
  277. }
  278. if (!this.selectionChecked.includes('运输')){
  279. this.totalElseCost += this.quoteDetail.shippingCost;
  280. }
  281. },
  282. computePriceByRate(val,type){
  283. if (val === undefined || val === null){
  284. return;
  285. }
  286. let value = 0;
  287. // 公式包含Tool +测试+其他+包装+运输
  288. let otherCost = this.quoteDetail.toolCost + this.quoteDetail.testCost + this.quoteDetail.elseCost + this.quoteDetail.packCost + this.quoteDetail.shippingCost
  289. let partCost = this.quoteDetail.toolCost + this.quoteDetail.adjustPartCost + this.quoteDetail.packCost + this.quoteDetail.shippingCost
  290. // 其他成本 + 材料成本 + 机器成本 + 人工成本
  291. let ttlCost = otherCost + this.quoteDetail.adjustPartCost + this.quoteDetail.adjustMachineCost + this.quoteDetail.adjustLabourCost;
  292. switch (type){
  293. case 'va':
  294. value = this.quoteDetail.quoteProfitRate/100
  295. if (1-value === 0){
  296. return;
  297. }
  298. //price = (物料成本+工具成本+运输成本+包装成本)/(1-value)+其他额外成本
  299. // this.quoteDetail.quoteTaxTotalPrice = (this.quoteDetail.adjustPartCost + otherCost)/(1-value)+this.totalElseCost
  300. this.quoteDetail.quoteTaxTotalPrice = (partCost)/(1-value)+this.totalElseCost
  301. // contribution = 1-(物料成本+人工成本+工具成本+运输成本+包装成本)/(price-额外其他成本)
  302. // this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustPartCost + this.quoteDetail.adjustLabourCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  303. this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustLabourCost + partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  304. // margin = (price-额外其他成本-总成本)/(price-额外其他成本)
  305. // this.quoteDetail.quoteTaxRate = ((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - ttlCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  306. this.quoteDetail.quoteTaxRate=((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - this.quoteDetail.totalCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  307. break;
  308. case 'contribution':
  309. value = this.quoteDetail.quoteProfitAmount/100
  310. //price = (物料成本+工具成本+运输成本+包装成本+人工成本)/(1-value)+其他额外成本
  311. // this.quoteDetail.quoteTaxTotalPzorice = (this.quoteDetail.adjustPartCost + this.quoteDetail.adjustLabourCost + otherCost)/(1-value)+this.totalElseCost
  312. // this.quoteDetail.quoteTaxTotalPrice = (partCost + this.quoteDetail.adjustLabourCost)/(1-this.quoteDetail.quoteProfitAmount)+this.totalElseCost
  313. this.quoteDetail.quoteTaxTotalPrice = (partCost + this.quoteDetail.adjustLabourCost)/(1-value)+this.totalElseCost
  314. // va = 1-(物料成本+工具成本+运输成本+包装成本)/(price-额外其他成本)
  315. // this.quoteDetail.quoteProfitRate = (1-(this.quoteDetail.adjustPartCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  316. this.quoteDetail.quoteProfitRate = (1-(partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  317. // margin = (price-额外其他成本-总成本)/(price-额外其他成本)
  318. // this.quoteDetail.quoteTaxRate=((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - ttlCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  319. this.quoteDetail.quoteTaxRate=((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - this.quoteDetail.totalCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  320. break;
  321. case 'margin':
  322. value = this.quoteDetail.quoteTaxRate/100
  323. // price = 总成本/(1-value)+其他额外成本
  324. // this.quoteDetail.quoteTaxTotalPrice = ttlCost/(1-value)+this.totalElseCost
  325. // this.quoteDetail.quoteTaxTotalPrice = ttlCost1/(1-this.quoteDetail.quoteTaxRate)+this.totalElseCost
  326. this.quoteDetail.quoteTaxTotalPrice = ttlCost1/(1-value)+this.totalElseCost
  327. // va = 1-(物料成本+工具成本+运输成本+包装成本)/(price-额外其他成本)
  328. // this.quoteDetail.quoteProfitRate = (1-(this.quoteDetail.adjustPartCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  329. this.quoteDetail.quoteProfitRate = (1-(partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  330. // contribution = 1-(物料成本+人工成本+工具成本+运输成本+包装成本)/(price-额外其他成本)
  331. // this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustPartCost + this.quoteDetail.adjustLabourCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  332. this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustLabourCost + partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  333. break;
  334. case 'price':
  335. value = this.quoteDetail.quoteTaxTotalPrice
  336. // va = 1-(物料成本+工具成本+运输成本+包装成本)/(value-额外其他成本)
  337. // this.quoteDetail.quoteProfitRate = (1-(this.quoteDetail.adjustPartCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  338. this.quoteDetail.quoteProfitRate = (1-(partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  339. // contribution = 1-(物料成本+人工成本+工具成本+运输成本+包装成本)/(value-额外其他成本)
  340. // this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustPartCost + this.quoteDetail.adjustLabourCost + otherCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  341. this.quoteDetail.quoteProfitAmount = (1-(this.quoteDetail.adjustLabourCost + partCost)/(this.quoteDetail.quoteTaxTotalPrice-this.totalElseCost))*100
  342. // margin = (value-额外其他成本-总成本)/(value-额外其他成本)
  343. // this.quoteDetail.quoteTaxRate=((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - ttlCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  344. this.quoteDetail.quoteTaxRate=((this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost - this.quoteDetail.totalCost)/(this.quoteDetail.quoteTaxTotalPrice - this.totalElseCost))*100
  345. break;
  346. }
  347. }
  348. },
  349. watch:{
  350. 'quoteDetail.adjustPartCost'(newValue, oldValue){
  351. if (newValue === undefined || newValue === null){
  352. this.$set(this.quoteDetail, 'adjustPartCost', 0);
  353. }
  354. this.computeTotalCost();
  355. },
  356. 'quoteDetail.adjustMachineCost'(newValue, oldValue){
  357. if (newValue === undefined || newValue === null){
  358. this.quoteDetail.adjustMachineCost = 0;
  359. }
  360. this.computeTotalCost();
  361. },
  362. 'quoteDetail.adjustFabricateCost'(newValue, oldValue){
  363. if (newValue === undefined || newValue === null){
  364. this.quoteDetail.adjustFabricateCost = 0;
  365. }
  366. this.computeTotalCost();
  367. },
  368. 'quoteDetail.adjustLabourCost'(newValue, oldValue){
  369. if (newValue === undefined || newValue === null){
  370. this.quoteDetail.adjustLabourCost = 0;
  371. }
  372. this.computeTotalCost();
  373. },
  374. 'quoteDetail.adjustToolCost'(newValue, oldValue){
  375. if (newValue === undefined || newValue === null){
  376. this.quoteDetail.adjustToolCost = 0;
  377. }
  378. this.computeTotalCost();
  379. },
  380. 'quoteDetail.adjustTestCost'(newValue, oldValue){
  381. if (newValue === undefined || newValue === null){
  382. this.quoteDetail.adjustTestCost = 0;
  383. }
  384. this.computeTotalCost();
  385. },
  386. 'quoteDetail.adjustElseCost'(newValue, oldValue){
  387. if (newValue === undefined || newValue === null){
  388. this.quoteDetail.adjustElseCost = 0;
  389. }
  390. this.computeTotalCost();
  391. },
  392. 'quoteDetail.manageCost'(newValue, oldValue){
  393. if (newValue === undefined || newValue === null){
  394. this.quoteDetail.manageCost = 0;
  395. }
  396. this.computeTotalCost();
  397. },
  398. 'quoteDetail.otherCost'(newValue, oldValue){
  399. if (newValue === undefined || newValue === null){
  400. this.quoteDetail.otherCost = 0;
  401. }
  402. this.computeTotalCost();
  403. },
  404. 'quoteDetail.profitRate'(newValue, oldValue){
  405. if (newValue === undefined || newValue === null){
  406. this.quoteDetail.profitRate = 0;
  407. }
  408. // this.quoteDetail.quoteProfitRate = newValue;
  409. this.computeTotalCost();
  410. },
  411. 'quoteDetail.taxRate'(newValue, oldValue){
  412. if (newValue === undefined || newValue === null){
  413. this.quoteDetail.taxRate = 0;
  414. }
  415. this.computeTotalCost();
  416. },
  417. 'quoteDetail.exchangeRate1'(newValue, oldValue){
  418. if (newValue === undefined || newValue === null){
  419. this.quoteDetail.exchangeRate1 = 0;
  420. }
  421. this.computeTotalCost();
  422. },
  423. 'quoteDetail.exchangeRate2'(newValue, oldValue){
  424. if (newValue === undefined || newValue === null){
  425. this.quoteDetail.exchangeRate2 = 0;
  426. }
  427. this.computeTotalCost();
  428. },
  429. 'quoteDetail.quoteCurrencyTotalCost1'(newValue, oldValue){
  430. if (newValue === undefined || newValue === null){
  431. this.quoteDetail.quoteCurrencyTotalCost1 = 0;
  432. }
  433. },
  434. 'quoteDetail.quoteCurrencyTotalCost2'(newValue, oldValue){
  435. if (newValue === undefined || newValue === null){
  436. this.quoteDetail.quoteCurrencyTotalCost2 = 0;
  437. }
  438. },
  439. 'quoteDetail.currencyTotalCost1'(newValue, oldValue){
  440. if (newValue === undefined || newValue === null){
  441. this.quoteDetail.currencyTotalCost1 = 0;
  442. }
  443. },
  444. 'quoteDetail.currencyTotalCost2'(newValue, oldValue){
  445. if (newValue === undefined || newValue === null){
  446. this.quoteDetail.currencyTotalCost2 = 0;
  447. }
  448. },
  449. 'quoteDetail.quoteTaxTotalPrice'(newValue, oldValue){
  450. if (newValue === undefined || newValue === null){
  451. this.quoteDetail.quoteTaxTotalPrice = 0;
  452. }
  453. this.computeTaxCost();
  454. },
  455. 'quoteDetail.currency1'(newValue, oldValue){
  456. this.quoteDetail.currency2 = newValue;
  457. },
  458. selectionChecked(newVal,oldVal){
  459. if (newVal.length === this.allCheckedLabel.length){
  460. this.checkAll = true;
  461. }else {
  462. this.checkAll = false;
  463. }
  464. },
  465. },
  466. computed:{
  467. selectionChecked:{
  468. set(newVal){
  469. this.selection = newVal.join(',')
  470. this.quoteDetail.calculatedItems = this.selection;
  471. this.computeTotalCost();
  472. },
  473. get(){
  474. if (this.selection === '' || this.selection === undefined || this.selection === null){
  475. return []
  476. }
  477. return this.selection.split(',')
  478. }
  479. },
  480. unitPrice(){
  481. if (this.quoteDetail.exchangeRate2 === 0){
  482. return 0
  483. }
  484. return this.quoteDetail.unitPrice/this.quoteDetail.exchangeRate2
  485. }
  486. },
  487. mounted() {
  488. if (this.quoteDetail.calculatedItems){
  489. this.selection = this.quoteDetail.calculatedItems;
  490. }
  491. this.$nextTick(()=>{
  492. this.computeProfitAmount()
  493. this.computedTotalPartCost();// 重新计算成本
  494. })
  495. }
  496. }
  497. </script>
  498. <template>
  499. <div>
  500. <template v-if="isAuth('5011:detail:tab7:compute')">
  501. <el-button :loading="computeLoading" style="margin-right: 10px" type="primary" :disabled="quoteDetail.status === '下达'" @click="handleQueryAllCost"> </el-button>
  502. </template>
  503. <el-popover
  504. placement="bottom-start"
  505. width="100"
  506. trigger="hover">
  507. <div>
  508. <el-checkbox :indeterminate="selectionChecked.length > 0 && selectionChecked.length < allCheckedLabel.length" v-model="checkAll" @change="changeAllCheck"> 全选 </el-checkbox>
  509. </div>
  510. <el-checkbox-group v-model="selectionChecked">
  511. <div v-for="label in allCheckedLabel">
  512. <el-checkbox :label="label" :key="label">{{label}}</el-checkbox>
  513. </div>
  514. </el-checkbox-group>
  515. <a slot="reference">计入材料成本</a>
  516. </el-popover>
  517. <!--系统自动计算结果-->
  518. <el-form :model="quoteDetail" ref="costForm" :rules="rules" label-position="top" label-width="120px">
  519. <div style="display: flex">
  520. <fieldset v-show="isShowCost"
  521. style="margin-top: 5px;border: 1px solid #777;width: 50%">
  522. <legend>系统自动计算结果(料工费)</legend>
  523. <el-row :gutter="10" >
  524. <el-col :span="8" v-show="!showQuoteCost">
  525. <el-form-item label="材料成本:" prop="partCost" :show-message="false">
  526. <el-input-number style="width: 100%; " :controls="false" v-model="quoteDetail.partCost" :precision="4" disabled/>
  527. </el-form-item>
  528. </el-col>
  529. <el-col :span="8">
  530. <el-form-item label="机器成本:" prop="machineCost" :show-message="false">
  531. <el-input-number style="width: 100%; " :controls="false"
  532. v-model="quoteDetail.machineCost" :precision="4" disabled/>
  533. </el-form-item>
  534. </el-col>
  535. <el-col :span="8">
  536. <el-form-item label="人工成本:" prop="labourCost" :show-message="false">
  537. <el-input-number style="width: 100%;" :controls="false"
  538. v-model="quoteDetail.labourCost" :precision="4" disabled/>
  539. </el-form-item>
  540. </el-col>
  541. </el-row>
  542. </fieldset>
  543. <fieldset
  544. style="margin-top: 5px;border: 1px solid #777;width: 50%">
  545. <legend>调整后成本(料工费)</legend>
  546. <el-row :gutter="10" >
  547. <el-col :span="8" v-show="!showQuoteCost">
  548. <el-form-item label="材料成本:" prop="adjustPartCost" :show-message="false">
  549. <el-input-number style="width: 100%;" :controls="false"
  550. v-model="quoteDetail.adjustPartCost" :disabled="quoteDetail.status === '下达'" :step="0" :precision="4" :min="0"/>
  551. </el-form-item>
  552. </el-col>
  553. <el-col :span="8">
  554. <el-form-item label="机器成本:" prop="adjustMachineCost" :show-message="false">
  555. <el-input-number style="width: 100%;" :controls="false"
  556. v-model="quoteDetail.adjustMachineCost" :disabled="quoteDetail.status === '下达'" :step="0" :precision="4" :min="0"/>
  557. </el-form-item>
  558. </el-col>
  559. <el-col :span="8">
  560. <el-form-item label="人工成本:" prop="adjustLabourCost" :show-message="false">
  561. <el-input-number style="width: 100%;" :controls="false"
  562. v-model="quoteDetail.adjustLabourCost" :disabled="quoteDetail.status === '下达'" :step="0" :precision="4" :min="0"/>
  563. </el-form-item>
  564. </el-col>
  565. </el-row>
  566. </fieldset>
  567. </div>
  568. <fieldset style="margin-top: 5px;border: 1px solid #777;">
  569. <legend>其他成本</legend>
  570. <el-row :gutter="10" >
  571. <el-col :span="4">
  572. <el-form-item label="工具成本:" prop="toolCost" :show-message="false">
  573. <el-input-number style="width: 100%;" :controls="false"
  574. v-model="quoteDetail.toolCost" :precision="4" disabled/>
  575. </el-form-item>
  576. </el-col>
  577. <el-col :span="4">
  578. <el-form-item label="测试成本:" prop="testCost" :show-message="false">
  579. <el-input-number style="width: 100%;" :controls="false"
  580. v-model="quoteDetail.testCost" :precision="4" disabled/>
  581. </el-form-item>
  582. </el-col>
  583. <el-col :span="4">
  584. <el-form-item label="包装成本:">
  585. <el-input-number style="width: 100%;" :controls="false"
  586. v-model="quoteDetail.packCost" :step="0" :precision="4" :min="0" disabled/>
  587. </el-form-item>
  588. </el-col>
  589. <el-col :span="4">
  590. <el-form-item label="运输成本:">
  591. <el-input-number style="width: 100%; " :controls="false"
  592. v-model="quoteDetail.shippingCost" :step="0" :precision="4" :min="0" disabled/>
  593. </el-form-item>
  594. </el-col>
  595. <el-col :span="4">
  596. <el-form-item label="其他成本:" prop="elseCost" :show-message="false">
  597. <el-input-number style="width: 100%;" :controls="false"
  598. v-model="quoteDetail.elseCost" :precision="4" disabled/>
  599. </el-form-item>
  600. </el-col>
  601. </el-row>
  602. </fieldset>
  603. <fieldset style="margin-top: 5px;border: 1px solid #777;">
  604. <legend>总成本</legend>
  605. <el-row :gutter="10" >
  606. <el-col :span="4">
  607. <el-form-item label="总成本:" prop="totalCost" :show-message="false">
  608. <el-input-number style="width: 100%;" :controls="false"
  609. v-model="quoteDetail.totalCost" :step="0" :precision="4" :min="0" disabled/>
  610. </el-form-item>
  611. </el-col>
  612. <el-col :span="4">
  613. <el-form-item label="总材料成本:" :show-message="false">
  614. <el-input-number style="width: 100%;" :controls="false"
  615. v-model="totalPartCost" :step="0" :precision="4" :min="0" disabled/>
  616. </el-form-item>
  617. </el-col>
  618. <el-col :span="4">
  619. <el-form-item label="额外添加其他成本:" :show-message="false">
  620. <el-input-number style="width: 100%;" :controls="false"
  621. v-model="totalElseCost" :step="0" :precision="4" :min="0" disabled/>
  622. </el-form-item>
  623. </el-col>
  624. </el-row>
  625. </fieldset>
  626. <fieldset style="margin-top: 5px;border: 1px solid #777;">
  627. <legend>利润</legend>
  628. <el-row :gutter="10" >
  629. <!-- <el-col :span="4">-->
  630. <!-- <el-form-item label="利润率%:" prop="profitRate" :show-message="false">-->
  631. <!-- <el-input-number style="width: 100%;" :controls="false"-->
  632. <!-- v-model="quoteDetail.profitRate" :disabled="quoteDetail.status === '下达'" :step="0" :min="0"/>-->
  633. <!-- </el-form-item>-->
  634. <!-- </el-col>-->
  635. <!-- <el-col :span="4">-->
  636. <!-- <el-form-item label="利润额:" prop="profitAmount" :show-message="false">-->
  637. <!-- <el-input-number style="width: 100%;" :controls="false"-->
  638. <!-- v-model="quoteDetail.profitAmount" :step="0" :precision="4" :min="0" disabled/>-->
  639. <!-- </el-form-item>-->
  640. <!-- </el-col>-->
  641. <el-col :span="4">
  642. <el-form-item label="VA%" :show-message="false">
  643. <el-input-number style="width: 60%;" @blur="(value)=>computePriceByRate(value,'va')" :controls="false"
  644. v-model="quoteDetail.quoteProfitRate" :disabled="quoteDetail.status === '下达' || editInput !== 'VA'" :step="0" :precision="0"/>
  645. <el-link v-if="editInput !== 'VA' && quoteDetail.status === '草稿'" @click="editInput = 'VA'"><i class="el-icon-edit"></i></el-link>
  646. </el-form-item>
  647. </el-col>
  648. <el-col :span="4">
  649. <el-form-item label="Contribution%" :show-message="false">
  650. <el-input-number style="width: 60%;" @blur="(value)=>computePriceByRate(value,'contribution')" :controls="false"
  651. v-model="quoteDetail.quoteProfitAmount" :disabled="quoteDetail.status === '下达' || editInput !== 'Contribution'" :step="0" :precision="0"/>
  652. <el-link v-if="editInput !== 'Contribution' && quoteDetail.status === '草稿'" @click="editInput = 'Contribution'"><i class="el-icon-edit"></i></el-link>
  653. </el-form-item>
  654. </el-col>
  655. <el-col :span="4">
  656. <el-form-item label="Margin%" :show-message="false">
  657. <el-input-number style="width: 60%;" @blur="(value)=>computePriceByRate(value,'margin')" :controls="false"
  658. v-model="quoteDetail.quoteTaxRate" :disabled="quoteDetail.status === '下达' || editInput !== 'Margin'" :step="0" :precision="0"/>
  659. <el-link v-if="editInput !== 'Margin' && quoteDetail.status === '草稿'" @click="editInput = 'Margin'"><i class="el-icon-edit"></i></el-link>
  660. </el-form-item>
  661. </el-col>
  662. <el-col :span="4">
  663. <el-form-item label="Price ¥(ex VAT)" :show-message="false">
  664. <el-input-number style="width: 60%;" @blur="(value)=>computePriceByRate(value,'price')" :controls="false"
  665. v-model="quoteDetail.quoteTaxTotalPrice" :disabled="quoteDetail.status === '下达'|| editInput !== 'Price'" :step="0" :min="0" :precision="4"/>
  666. <el-link v-if="editInput !== 'Price' && quoteDetail.status === '草稿'" @click="editInput = 'Price'"><i class="el-icon-edit"></i></el-link>
  667. </el-form-item>
  668. </el-col>
  669. </el-row>
  670. </fieldset>
  671. <fieldset style="margin-top: 5px;border: 1px solid #777;">
  672. <legend>最终价格</legend>
  673. <el-row :gutter="10">
  674. <el-col :span="4">
  675. <el-form-item label="未税单价(CNY):" prop="unitPrice" :show-message="false">
  676. <el-input-number style="width: 100%;" :controls="false"
  677. v-model="quoteDetail.unitPrice" :step="0" :min="0" :precision="4" disabled/>
  678. </el-form-item>
  679. </el-col>
  680. <el-col :span="4">
  681. <el-form-item label="税率%:" prop="taxRate" :show-message="false">
  682. <el-input-number style="width: 100%;" :controls="false"
  683. v-model="quoteDetail.taxRate" :disabled="quoteDetail.status === '下达'" :step="0" :min="0"/>
  684. </el-form-item>
  685. </el-col>
  686. <el-col :span="4">
  687. <el-form-item label="其他税率%:" prop="exchangeRate1" :show-message="false">
  688. <el-input-number style="width: 100%;" :controls="false"
  689. v-model="quoteDetail.exchangeRate1" :disabled="quoteDetail.status === '下达'" :step="0" :min="0"/>
  690. </el-form-item>
  691. </el-col>
  692. <el-col :span="4">
  693. <el-form-item label="含税单价(CNY):" prop="taxUnitPrice" :show-message="false">
  694. <el-input-number style="width: 100%;" :controls="false"
  695. v-model="quoteDetail.taxUnitPrice" :step="0" :precision="4" :min="0" disabled/>
  696. </el-form-item>
  697. </el-col>
  698. </el-row>
  699. <el-row :gutter="10">
  700. <el-col :span="4">
  701. <el-form-item label="未税单价">
  702. <el-input-number style="width: 100%;" v-model="unitPrice" :controls="false" :step="0" :precision="4" :min="0" disabled></el-input-number>
  703. </el-form-item>
  704. </el-col>
  705. <el-col :span="4">
  706. <el-form-item label="币种:">
  707. <dict-data-select v-model="quoteDetail.currency2" disabled
  708. clearable dict-type="plm_customer_information_customer_customer_currency" :use-default-value="true"></dict-data-select>
  709. </el-form-item>
  710. </el-col>
  711. <el-col :span="4">
  712. <el-form-item label="汇率:">
  713. <el-input-number style="width: 100%;" :controls="false"
  714. v-model="quoteDetail.exchangeRate2" :disabled="quoteDetail.status === '下达'" :step="0" :min="0"/>
  715. </el-form-item>
  716. </el-col>
  717. <el-col :span="4">
  718. <el-form-item label="含税单价:">
  719. <el-input-number style="width: 100%;" :controls="false"
  720. v-model="quoteDetail.currencyTotalCost2" disabled :step="0" :min="0" :precision="4"/>
  721. </el-form-item>
  722. </el-col>
  723. </el-row>
  724. </fieldset>
  725. </el-form>
  726. </div>
  727. </template>
  728. <style scoped>
  729. </style>