inventoryTable.vue 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650
  1. <template>
  2. <el-form ref="form" :model="form" :rules="rules">
  3. <ele-pro-table
  4. ref="table"
  5. :needPage="false"
  6. :columns="columns"
  7. :datasource="form.datasource"
  8. class="time-form"
  9. height="300"
  10. full-height="calc(100vh - 76px)"
  11. @columns-change="handleColumnChange"
  12. :cache-key="cacheKeyUrl"
  13. :selection.sync="selection"
  14. :show-summary="showSummary"
  15. :summary-method="getSummaries"
  16. >
  17. <!-- 表头工具栏 -->
  18. <template v-slot:toolbar>
  19. <div class="headbox">
  20. <div>
  21. <el-button
  22. size="small"
  23. type="primary"
  24. icon="el-icon-plus"
  25. class="ele-btn-icon"
  26. @click="handParent('', -1)"
  27. >
  28. 新增
  29. </el-button>
  30. <el-button
  31. size="small"
  32. type="primary"
  33. icon="el-icon-plus"
  34. class="ele-btn-icon"
  35. v-if="isGoods"
  36. @click="handGoods(-1)"
  37. >
  38. 选择商品
  39. </el-button>
  40. <el-button
  41. size="small"
  42. type="primary"
  43. icon="el-icon-plus"
  44. class="ele-btn-icon"
  45. v-if="isTemporary"
  46. @click="handlAdd"
  47. >
  48. 新增临时产品
  49. </el-button>
  50. <el-button
  51. size="small"
  52. type="primary"
  53. class="ele-btn-icon"
  54. @click="save"
  55. v-if="isDrawer"
  56. >
  57. 保存
  58. </el-button>
  59. <setAllValue
  60. :disabled="!selection.length"
  61. title="客户期望交期"
  62. @success="setAllValueChange"
  63. valueKey="customerExpectDeliveryDeadline"
  64. />
  65. <setAllValue
  66. :disabled="!selection.length"
  67. title="生产交付交期"
  68. valueKey="produceDeliveryDeadline"
  69. @success="setAllValueChange"
  70. />
  71. </div>
  72. <div class="pricebox">
  73. <span class="amount">总计:{{ allPrice }}元</span>
  74. <el-form-item
  75. style="width: 300px"
  76. v-if="isDiscountTotalPrice"
  77. label="优惠后总金额:"
  78. prop="discountTotalPrice"
  79. :rules="{
  80. required: true,
  81. message: '请输入优惠后总金额',
  82. trigger: 'change'
  83. }"
  84. >
  85. <el-input
  86. type="number"
  87. :min="0"
  88. :max="allPrice"
  89. :disabled="!allPrice"
  90. v-model="form.discountTotalPrice"
  91. style="width: 180px"
  92. placeholder="请输入"
  93. @input="discountInputByOrder(form.discountTotalPrice)"
  94. >
  95. <template slot="append">元</template>
  96. </el-input>
  97. </el-form-item>
  98. </div>
  99. </div>
  100. </template>
  101. <template v-slot:productName="{ row, $index }">
  102. <el-form-item
  103. :prop="'datasource.' + $index + '.productName'"
  104. :rules="{
  105. required: true,
  106. message: '请输入',
  107. trigger: 'change'
  108. }"
  109. >
  110. <el-input
  111. :disabled="!!row.productId && row.productId != 0"
  112. v-model="row.productName"
  113. placeholder="请输入"
  114. style="width: 60%; margin-right: 10px"
  115. ></el-input>
  116. <el-button
  117. size="small"
  118. type="primary"
  119. @click.native="handParent(row, $index)"
  120. >选择
  121. </el-button>
  122. </el-form-item>
  123. </template>
  124. <template v-slot:entrustedEnterpriseId="scope">
  125. <el-form-item prop="entrustedEnterpriseId">
  126. <el-select
  127. v-model="scope.row.entrustedEnterpriseId"
  128. clearable
  129. filterable
  130. >
  131. <el-option
  132. v-for="i in scope.row.entrustedEnterpriseIdList"
  133. :key="i.id"
  134. :value="i.id"
  135. :label="i.name"
  136. ></el-option>
  137. </el-select>
  138. </el-form-item>
  139. </template>
  140. <template v-slot:headerCustomerMark="{ column }">
  141. <span class="is-required">{{ column.label }}</span>
  142. </template>
  143. <template v-slot:customerMark="{ row, $index }">
  144. <el-form-item
  145. :prop="'datasource.' + $index + '.customerMark'"
  146. :rules="{
  147. required: isCustomerMark ? true : false,
  148. message: '请输入客户代号',
  149. trigger: 'change'
  150. }"
  151. >
  152. <el-input
  153. v-model="row.customerMark"
  154. :disabled="quoteType === 2"
  155. placeholder="请输入"
  156. ></el-input>
  157. </el-form-item>
  158. </template>
  159. <template v-slot:headerProductName="{ column }">
  160. <span class="is-required">{{ column.label }}</span>
  161. </template>
  162. <template v-slot:productCode="scope">
  163. <el-form-item :prop="'datasource.' + scope.$index + '.productCode'">
  164. <el-input
  165. v-model="scope.row.productCode"
  166. :disabled="
  167. quoteType != 2 ||
  168. (!!scope.row.productId && scope.row.productId != 0)
  169. "
  170. ></el-input>
  171. </el-form-item>
  172. </template>
  173. <template v-slot:productCategoryName="scope">
  174. <el-form-item
  175. :prop="'datasource.' + scope.$index + '.productCategoryName'"
  176. >
  177. <el-input v-model="scope.row.productCategoryName" disabled></el-input>
  178. </el-form-item>
  179. </template>
  180. <template v-slot:headerTotalCount="{ column }">
  181. <span :class="{ 'is-required': isTotalCount }">{{ column.label }}</span>
  182. </template>
  183. <template v-slot:headerTaxRate="{ column }">
  184. <span class="is-required">{{ column.label }}</span>
  185. </template>
  186. <template v-slot:totalPrice="scope">
  187. <el-form-item :prop="'datasource.' + scope.$index + '.totalPrice'">
  188. {{ formatPrice(Number(scope.row.totalPrice) || 0) }}元
  189. </el-form-item>
  190. </template>
  191. <template v-slot:productBrand="scope">
  192. <el-form-item :prop="'datasource.' + scope.$index + '.productBrand'">
  193. <el-input
  194. v-model="scope.row.productBrand"
  195. :disabled="!!scope.row.productId && scope.row.productId != 0"
  196. ></el-input>
  197. </el-form-item>
  198. </template>
  199. <template v-slot:modelType="scope">
  200. <el-form-item :prop="'datasource.' + scope.$index + '.modelType'">
  201. <el-input
  202. v-model="scope.row.modelType"
  203. :disabled="!!scope.row.productId && scope.row.productId != 0"
  204. ></el-input>
  205. </el-form-item>
  206. </template>
  207. <template v-slot:specification="scope">
  208. <el-form-item :prop="'datasource.' + scope.$index + '.specification'">
  209. <el-input
  210. v-model="scope.row.specification"
  211. :disabled="!!scope.row.productId && scope.row.productId != 0"
  212. ></el-input>
  213. </el-form-item>
  214. </template>
  215. <template v-slot:guaranteePeriod="scope">
  216. <div class="period">
  217. <div class="borderleftnone">
  218. <el-form-item
  219. :prop="'datasource.' + scope.$index + '.guaranteePeriod'"
  220. :rules="{
  221. pattern: numberReg,
  222. message: '请输入有效期',
  223. trigger: 'blur'
  224. }"
  225. >
  226. <el-input
  227. v-model="scope.row.guaranteePeriod"
  228. @change="
  229. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  230. "
  231. placeholder="请输入"
  232. ></el-input>
  233. </el-form-item>
  234. </div>
  235. <div class="borderrightnone">
  236. <DictSelection
  237. dictName="质保期单位"
  238. clearable
  239. v-model="scope.row.guaranteePeriodUnitCode"
  240. @change="
  241. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  242. "
  243. :isOne="scope.$index === 0"
  244. >
  245. </DictSelection>
  246. </div>
  247. </div>
  248. </template>
  249. <!-- <template v-slot:measuringUnit="scope">
  250. <el-form-item :prop="'datasource.' + scope.$index + '.measuringUnit'">
  251. <el-input
  252. v-model="scope.row.measuringUnit"
  253. :disabled="!!scope.row.productCode"
  254. placeholder="请输入"
  255. ></el-input>
  256. </el-form-item>
  257. </template> -->
  258. <template v-slot:remark="scope">
  259. <el-form-item :prop="'datasource.' + scope.$index + '.remark'">
  260. <el-input
  261. v-model="scope.row.remark"
  262. type="textarea"
  263. placeholder="请输入"
  264. ></el-input>
  265. </el-form-item>
  266. </template>
  267. <template v-slot:singlePrice="scope">
  268. <el-form-item
  269. :prop="'datasource.' + scope.$index + '.singlePrice'"
  270. :rules="{
  271. required: quoteType !== 2 && isSinglePrice ? true : false,
  272. message: '请输入单价',
  273. trigger: 'change'
  274. }"
  275. >
  276. <el-input
  277. v-model="scope.row.singlePrice"
  278. placeholder="请输入"
  279. :disabled="quoteType === 2"
  280. @input="handleCountChange(scope.row, scope.$index)"
  281. type="number"
  282. >
  283. <template slot="append">元</template>
  284. </el-input>
  285. </el-form-item>
  286. </template>
  287. <template v-slot:taxRate="scope">
  288. <el-form-item
  289. :prop="'datasource.' + scope.$index + '.taxRate'"
  290. :rules="{
  291. required: isTaxRate == 1 ? true : false,
  292. message: '请输入税率',
  293. trigger: 'change'
  294. }"
  295. >
  296. <el-input
  297. v-model="scope.row.taxRate"
  298. placeholder="请输入"
  299. type="number"
  300. :disabled="quoteType === 2"
  301. @input="getNotaxSinglePrice"
  302. >
  303. <template slot="append">%</template>
  304. </el-input>
  305. </el-form-item>
  306. </template>
  307. <template v-slot:headerSinglePrice="{ column }">
  308. <span :class="isSinglePrice ? 'is-required' : ''">{{
  309. column.label
  310. }}</span>
  311. </template>
  312. <template v-slot:headerCustomerExpectDeliveryDeadline="{ column }">
  313. <span :class="isDate == 1 ? 'is-required' : ''">{{
  314. column.label
  315. }}</span>
  316. </template>
  317. <template v-slot:technicalAnswerName="{ row, $index }">
  318. <el-form-item :prop="'datasource.' + $index + '.technicalAnswerName'">
  319. <el-input
  320. v-model="row.technicalAnswerName"
  321. placeholder="请输入"
  322. @click.native="handHead(row, $index)"
  323. ></el-input>
  324. </el-form-item>
  325. </template>
  326. <template v-slot:technicalParams="scope">
  327. <el-form-item :prop="'datasource.' + scope.$index + '.technicalParams'">
  328. <el-input
  329. type="textarea"
  330. v-model="scope.row.technicalParams"
  331. placeholder="请输入"
  332. ></el-input>
  333. </el-form-item>
  334. </template>
  335. <template v-slot:technicalDrawings="scope">
  336. <el-form-item
  337. :prop="'datasource.' + scope.$index + '.technicalDrawings'"
  338. >
  339. <fileMain v-model="scope.row.technicalDrawings"></fileMain>
  340. </el-form-item>
  341. </template>
  342. <template v-slot:customerReqFiles="scope">
  343. <el-form-item
  344. :prop="'datasource.' + scope.$index + '.customerReqFiles'"
  345. >
  346. <fileMain v-model="scope.row.customerReqFiles"></fileMain>
  347. </el-form-item>
  348. </template>
  349. <template v-slot:industryArtFiles="scope">
  350. <el-form-item
  351. :prop="'datasource.' + scope.$index + '.industryArtFiles'"
  352. :rules="{
  353. required: false,
  354. message: '请输入',
  355. trigger: 'change'
  356. }"
  357. >
  358. <fileMain v-model="scope.row.industryArtFiles"></fileMain>
  359. </el-form-item>
  360. </template>
  361. <template v-slot:otherFiles="scope">
  362. <el-form-item :prop="'datasource.' + scope.$index + '. otherFiles'">
  363. <fileMain v-model="scope.row.otherFiles"></fileMain>
  364. </el-form-item>
  365. </template>
  366. <template v-slot:headerProduceDeliveryDeadline="{ column }">
  367. <span
  368. :class="isProduceDeliveryDeadline && isDate == 1 ? 'is-required' : ''"
  369. >{{ column.label }}</span
  370. >
  371. </template>
  372. <template v-slot:produceDeliveryDeadline="scope">
  373. <el-form-item
  374. :prop="'datasource.' + scope.$index + '.produceDeliveryDeadline'"
  375. :rules="{
  376. required: isProduceDeliveryDeadline && isDate == 1 ? true : false,
  377. message: '选择生产交付交期',
  378. trigger: 'change'
  379. }"
  380. >
  381. <el-date-picker
  382. style="width: 140px"
  383. value-format="yyyy-MM-dd"
  384. v-model="scope.row.produceDeliveryDeadline"
  385. @change="
  386. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  387. "
  388. type="date"
  389. placeholder="选择日期"
  390. >
  391. </el-date-picker>
  392. </el-form-item>
  393. </template>
  394. <template v-slot:customerExpectDeliveryDeadline="scope">
  395. <el-form-item
  396. v-if="scope.row.arrivalWay == 1 || !scope.row.arrivalWay"
  397. :rules="{
  398. required: isDate == 1 && quoteType != 2 ? true : false,
  399. message:
  400. contractBookType == 1 ? '请选择客户期望交期' : '请选择交付日期',
  401. trigger: 'change'
  402. }"
  403. :prop="
  404. 'datasource.' + scope.$index + '.customerExpectDeliveryDeadline'
  405. "
  406. >
  407. <el-date-picker
  408. style="width: 140px"
  409. v-model="scope.row.customerExpectDeliveryDeadline"
  410. value-format="yyyy-MM-dd"
  411. @change="
  412. setDeliveryDays(scope.row, scope.$index, 'guaranteePeriod')
  413. "
  414. type="date"
  415. placeholder="选择日期"
  416. >
  417. </el-date-picker>
  418. </el-form-item>
  419. <el-form-item v-if="scope.row.arrivalWay == 2">
  420. <el-link
  421. type="primary"
  422. :underline="false"
  423. @click.native="handleMethod(scope.row, scope.$index)"
  424. >
  425. 设置分批时间
  426. </el-link>
  427. </el-form-item>
  428. </template>
  429. <template v-slot:provenance="scope">
  430. <el-form-item :prop="'datasource.' + scope.$index + '.provenance'">
  431. <DictSelection
  432. dictName="产地"
  433. clearable
  434. v-model="scope.row.provenance"
  435. :disabled="quoteType === 2"
  436. collapse-tags
  437. multiple
  438. :isOne="scope.$index === 0"
  439. >
  440. </DictSelection>
  441. </el-form-item>
  442. </template>
  443. <template v-slot:guaranteePeriodDeadline="scope">
  444. <el-form-item
  445. :prop="'datasource.' + scope.$index + '.guaranteePeriodDeadline'"
  446. >
  447. <el-date-picker
  448. style="width: 140px"
  449. v-model="scope.row.guaranteePeriodDeadline"
  450. type="date"
  451. value-format="yyyy-MM-dd"
  452. placeholder="选择日期"
  453. >
  454. </el-date-picker>
  455. </el-form-item>
  456. </template>
  457. <template v-slot:singleWeight="scope">
  458. <el-form-item :prop="'datasource.' + scope.$index + '.singleWeight'">
  459. <el-input
  460. v-model="scope.row.singleWeight"
  461. @input="handleCountChange(scope.row, scope.$index)"
  462. placeholder="请输入"
  463. >
  464. <template slot="append">
  465. <span v-if="!!scope.row.productId && scope.row.productId != 0">
  466. {{ scope.row.weightUnit }}
  467. </span>
  468. <el-input
  469. v-else
  470. v-model="scope.row.weightUnit"
  471. placeholder="单位"
  472. style="width: 80px; padding: 0"
  473. ></el-input>
  474. </template>
  475. </el-input>
  476. </el-form-item>
  477. </template>
  478. <template v-slot:totalWeight="scope">
  479. <el-form-item
  480. style="margin-bottom: 20px"
  481. :rules="{
  482. required: false,
  483. pattern: numberReg,
  484. trigger: 'change'
  485. }"
  486. :prop="'datasource.' + scope.$index + '.totalWeight'"
  487. >
  488. <el-input
  489. v-model="scope.row.totalWeight"
  490. @input="handleCountChange(scope.row, scope.$index, 'totalWeight')"
  491. placeholder="请输入"
  492. >
  493. <template slot="append">
  494. {{ scope.row.weightUnit }}
  495. </template>
  496. </el-input>
  497. </el-form-item>
  498. </template>
  499. <template v-slot:increaseTotalWeight="scope">
  500. <el-form-item
  501. :prop="'datasource.' + scope.$index + '.increaseTotalWeight'"
  502. >
  503. <el-input
  504. v-model="scope.row.increaseTotalWeight"
  505. @input="setIncreaseTotalWeight(scope.row, scope.$index)"
  506. placeholder="请输入"
  507. >
  508. <template slot="append">
  509. <span v-if="!!scope.row.productId && scope.row.productId != 0">
  510. {{ scope.row.weightUnit }}
  511. </span>
  512. <el-input
  513. v-else
  514. v-model="scope.row.weightUnit"
  515. placeholder="单位"
  516. style="width: 80px; padding: 0"
  517. ></el-input>
  518. </template>
  519. </el-input>
  520. </el-form-item>
  521. </template>
  522. <template v-slot:technologyRouteName="scope">
  523. <el-form-item
  524. :prop="'datasource.' + scope.$index + '.technologyRouteName'"
  525. :rules="{
  526. required: false,
  527. message: '请选择',
  528. trigger: 'change'
  529. }"
  530. >
  531. <el-input
  532. v-model="scope.row.technologyRouteName"
  533. placeholder="请选择"
  534. @click.native="openVersion(scope.$index)"
  535. ></el-input>
  536. </el-form-item>
  537. </template>
  538. <template v-slot:pricingWay="scope">
  539. <el-form-item :prop="'datasource.' + scope.$index + '.pricingWay'">
  540. <el-select
  541. v-model="scope.row.pricingWay"
  542. placeholder="请选择"
  543. :rules="{
  544. required: true,
  545. message: '请选择计价方式',
  546. trigger: 'change'
  547. }"
  548. @change="changeCount(scope.row, scope.$index)"
  549. >
  550. <el-option
  551. v-for="item in pricingWayList"
  552. :key="item.id"
  553. :label="item.name"
  554. :value="item.id"
  555. >
  556. </el-option>
  557. </el-select>
  558. </el-form-item>
  559. </template>
  560. <template v-slot:headerPricingWay="{ column }">
  561. <span class="is-required">{{ column.label }}</span>
  562. </template>
  563. <template v-slot:taskName="scope">
  564. <el-form-item :prop="'datasource.' + scope.$index + '.taskName'">
  565. <el-input
  566. v-model="scope.row.taskName"
  567. placeholder="请选择"
  568. style="width: 60%; margin-right: 10px"
  569. disabled
  570. ></el-input>
  571. <el-button
  572. size="small"
  573. type="primary"
  574. @click.native="handleTaskinstance(scope.row, scope.$index)"
  575. >选择
  576. </el-button>
  577. </el-form-item>
  578. </template>
  579. <template v-slot:arrivalWay="scope">
  580. <el-form-item :prop="'datasource.' + scope.$index + '.arrivalWay'">
  581. <el-select
  582. v-model="scope.row.arrivalWay"
  583. clearable
  584. style="width: 100%"
  585. >
  586. <el-option
  587. v-for="item in arrivalWayList"
  588. :key="item.value"
  589. :label="item.label"
  590. :value="item.value"
  591. >
  592. </el-option>
  593. </el-select>
  594. </el-form-item>
  595. </template>
  596. <template v-slot:batchNo="scope">
  597. <el-form-item
  598. :prop="'datasource.' + scope.$index + '.batchNo'"
  599. :rules="[
  600. {
  601. required: isBatchNo == 1 ? true : false,
  602. message: '请输入批号',
  603. trigger: 'blur'
  604. }
  605. ]"
  606. >
  607. <el-input
  608. v-model="scope.row.batchNo"
  609. placeholder="请输入"
  610. :disabled="quoteType === 2"
  611. v-no-chinese
  612. >
  613. </el-input>
  614. </el-form-item>
  615. </template>
  616. <template v-slot:headerBatchNo="{ column }">
  617. <span class="is-required">{{ column.label }}</span>
  618. </template>
  619. <template v-slot:orderNo="{ row, $index }">
  620. <el-form-item :prop="'datasource.' + $index + '.orderNo'">
  621. <el-select v-model="row.orderNo" style="width: 100%">
  622. <el-option
  623. :label="item.orderNo"
  624. :value="item.orderNo"
  625. @click.native="orderNoChange(row, item)"
  626. v-for="(item, index) in orderOption"
  627. :key="index"
  628. ></el-option>
  629. </el-select>
  630. </el-form-item>
  631. </template>
  632. <template v-slot:goodsLevel="{ row, $index }">
  633. <el-form-item :prop="'datasource.' + $index + '.goodsLevel'">
  634. <el-select
  635. v-model="row.goodsLevel"
  636. style="width: 100%"
  637. :disabled="quoteType === 2"
  638. >
  639. <el-option
  640. :label="item.label"
  641. :value="item.value"
  642. v-for="(item, index) in levelList"
  643. :key="index"
  644. ></el-option>
  645. </el-select>
  646. </el-form-item>
  647. </template>
  648. <template v-slot:goodsPriceType="{ row, $index }">
  649. <el-form-item :prop="'datasource.' + $index + '.goodsPriceType'">
  650. <DictSelection
  651. dictName="商品价格类型"
  652. clearable
  653. :disabled="quoteType === 2"
  654. v-model="row.goodsPriceType"
  655. @change="goodsPriceTypeChange(row, $index)"
  656. :isOne="$index === 0"
  657. >
  658. </DictSelection>
  659. </el-form-item>
  660. </template>
  661. <template v-slot:saleCount="scope">
  662. <el-form-item
  663. :prop="'datasource.' + scope.$index + '.' + countObj.countKey"
  664. :rules="{
  665. required: quoteType !== 2 && isTotalCount ? true : false,
  666. message: '请输入数量',
  667. trigger: 'change'
  668. }"
  669. >
  670. <el-input
  671. v-model="scope.row[countObj.countKey]"
  672. style="width: calc(100% - 36px)"
  673. placeholder="请输入"
  674. type="number"
  675. :min="0"
  676. @input="handleCountChange(scope.row, scope.$index)"
  677. >
  678. <template slot="append">
  679. <el-select
  680. v-model="scope.row[countObj.unitIdKey]"
  681. style="width: 100px"
  682. v-if="!!scope.row.productId && scope.row.productId != 0"
  683. @change="handleCountChange(scope.row, scope.$index)"
  684. >
  685. <el-option
  686. :label="item.conversionUnit"
  687. :value="item.id"
  688. v-for="(item, index) in scope.row.packageDispositionList"
  689. :key="index"
  690. ></el-option>
  691. </el-select>
  692. <el-input
  693. v-else
  694. v-model="scope.row.measuringUnit"
  695. placeholder="单位"
  696. style="width: 100px; padding: 0"
  697. ></el-input>
  698. </template>
  699. </el-input>
  700. </el-form-item>
  701. </template>
  702. <template v-slot:quoteWay="scope">
  703. <el-form-item
  704. :prop="'datasource.' + scope.$index + '.quoteWay'"
  705. :rules="{
  706. required: true,
  707. message: '请选择报价方式',
  708. trigger: 'change'
  709. }">
  710. <el-select
  711. v-model="scope.row.quoteWay"
  712. clearable
  713. filterable
  714. >
  715. <el-option
  716. v-for="i in quoteTypeOp"
  717. :key="i.value"
  718. :value="i.value"
  719. :label="i.label"
  720. ></el-option>
  721. </el-select>
  722. </el-form-item>
  723. </template>
  724. <template v-slot:headerQuoteWay="{ column }">
  725. <span class="is-required">{{ column.label }}</span>
  726. </template>
  727. <template v-slot:discountRatio="scope">
  728. <el-form-item
  729. :prop="'datasource.' + scope.$index + '.discountRatio'"
  730. :rules="{
  731. required: isDiscount == 1 ? true : false,
  732. message: '请输入折让比例',
  733. trigger: 'change'
  734. }"
  735. >
  736. <el-input
  737. v-model="scope.row.discountRatio"
  738. placeholder="请输入"
  739. type="number"
  740. :min="0"
  741. :max="100"
  742. :disabled="quoteType === 2"
  743. @input="getDiscountRatioPrice(scope.row)"
  744. >
  745. <template slot="append">%</template>
  746. </el-input>
  747. </el-form-item>
  748. </template>
  749. <template v-slot:headerDiscountRatio="{ column }">
  750. <span :class="isDiscount ? 'is-required' : ''">{{
  751. column.label
  752. }}</span>
  753. </template>
  754. <!-- <template v-slot:saleUnit="scope">
  755. <el-form-item
  756. :prop="'datasource.' + scope.$index + '.' + countObj.unitIdKey"
  757. >
  758. <el-select
  759. v-model="scope.row[countObj.unitIdKey]"
  760. style="width: 100%"
  761. @change="changeCount(scope.row, scope.$index)"
  762. >
  763. <el-option
  764. :label="item.conversionUnit"
  765. :value="item.id"
  766. @click.native="packingChange(item, scope.$index)"
  767. v-for="(item, index) in scope.row.packageDispositionList"
  768. :key="index"
  769. ></el-option>
  770. </el-select>
  771. </el-form-item>
  772. </template> -->
  773. <template v-slot:modelKey="scope">
  774. <el-form-item :prop="'datasource.' + scope.$index + '.' + 'modelKey'">
  775. <DictSelection
  776. dictName="物品机型"
  777. clearable
  778. :disabled="quoteType === 2"
  779. v-model="scope.row.modelKey"
  780. :isOne="scope.$index === 0"
  781. filterable
  782. allow-create
  783. default-first-option
  784. multiple
  785. >
  786. </DictSelection>
  787. </el-form-item>
  788. </template>
  789. <template v-slot:colorKey="scope">
  790. <el-form-item :prop="'datasource.' + scope.$index + '.' + 'colorKey'">
  791. <DictSelection
  792. dictName="物品颜色"
  793. clearable
  794. v-model="scope.row.colorKey"
  795. :isOne="scope.$index === 0"
  796. filterable
  797. allow-create
  798. default-first-option
  799. multiple
  800. >
  801. </DictSelection>
  802. </el-form-item>
  803. </template>
  804. <!-- 生产加工类型特有列的模板 -->
  805. <template v-slot:thickNess="{ row, $index }">
  806. <el-form-item :prop="'datasource.' + $index + '.thickNess'">
  807. <el-input v-model="row.thickNess" placeholder="请输入">
  808. <template slot="append">mm</template></el-input
  809. >
  810. </el-form-item>
  811. </template>
  812. <template v-slot:squareNumber="{ row, $index }">
  813. <el-form-item :prop="'datasource.' + $index + '.squareNumber'">
  814. <el-input v-model="row.squareNumber" placeholder="请输入">
  815. <template slot="append">m²</template></el-input
  816. >
  817. </el-form-item>
  818. </template>
  819. <template v-slot:processingFeeBeforeTax="{ row, $index }">
  820. <el-form-item
  821. :prop="'datasource.' + $index + '.processingFeeBeforeTax'"
  822. >
  823. <el-input
  824. v-model="row.processingFeeBeforeTax"
  825. type="number"
  826. placeholder="请输入"
  827. @input="calculateIncludingTaxPrice(row, $index)"
  828. >
  829. <template slot="append">元</template>
  830. </el-input>
  831. </el-form-item>
  832. </template>
  833. <template v-slot:packagingFeeNotTaxed="{ row, $index }">
  834. <el-form-item :prop="'datasource.' + $index + '.packagingFeeNotTaxed'">
  835. <el-input
  836. v-model="row.packagingFeeNotTaxed"
  837. type="number"
  838. placeholder="请输入"
  839. @input="calculateIncludingTaxPrice(row, $index)"
  840. >
  841. <template slot="append">元</template>
  842. </el-input>
  843. </el-form-item>
  844. </template>
  845. <template v-slot:transportationFeeWithoutTax="{ row, $index }">
  846. <el-form-item
  847. :prop="'datasource.' + $index + '.transportationFeeWithoutTax'"
  848. >
  849. <el-input
  850. v-model="row.transportationFeeWithoutTax"
  851. type="number"
  852. placeholder="请输入"
  853. @input="calculateIncludingTaxPrice(row, $index)"
  854. >
  855. <template slot="append">元</template>
  856. </el-input>
  857. </el-form-item>
  858. </template>
  859. <!-- 新增未税小记列模板 -->
  860. <template v-slot:quotationSubtotalBeforeTax="{ row, $index }">
  861. <el-form-item
  862. :prop="'datasource.' + $index + '.quotationSubtotalBeforeTax'"
  863. >
  864. {{ (Number(row.quotationSubtotalBeforeTax) || 0).toFixed(2) }}元
  865. </el-form-item>
  866. </template>
  867. <template v-slot:extraTax="{ row, $index }">
  868. <el-form-item :prop="'datasource.' + $index + '.extraTax'">
  869. <el-input
  870. v-model="row.extraTax"
  871. type="number"
  872. placeholder="请输入"
  873. @input="calculateIncludingTaxPrice(row, $index)"
  874. >
  875. <template slot="append">%</template>
  876. </el-input>
  877. </el-form-item>
  878. </template>
  879. <!-- 含税单价改为含税小计 -->
  880. <template v-slot:quotationSubtotalTax="{ row, $index }">
  881. <el-form-item :prop="'datasource.' + $index + '.quotationSubtotalTax'">
  882. {{ (Number(row.quotationSubtotalTax) || 0).toFixed(2) }}元
  883. <!-- <el-input
  884. v-model="row.quotationSubtotalTax"
  885. type="number"
  886. placeholder="请输入"
  887. >
  888. <template slot="append">元</template>
  889. </el-input> -->
  890. </el-form-item>
  891. </template>
  892. <template v-slot:productionRequirements="{ row, $index }">
  893. <el-form-item
  894. :prop="'datasource.' + $index + '.productionRequirements'"
  895. >
  896. <el-input
  897. v-model="row.productionRequirements"
  898. placeholder="请输入"
  899. type="textarea"
  900. >
  901. </el-input>
  902. </el-form-item>
  903. </template>
  904. <!-- 操作列 -->
  905. <template v-slot:action="scope">
  906. <el-popconfirm
  907. class="ele-action"
  908. title="确定要删除吗?"
  909. @confirm="remove(scope.$index)"
  910. >
  911. <template v-slot:reference>
  912. <el-link type="danger" :underline="false" icon="el-icon-delete">
  913. 删除
  914. </el-link>
  915. </template>
  916. </el-popconfirm>
  917. </template>
  918. </ele-pro-table>
  919. <product-list
  920. ref="productListRef"
  921. classType="1"
  922. :is-get-inventory-total="true"
  923. @changeParent="changeParent"
  924. :isSupplier="isSupplier"
  925. :isSalesRecord="isSalesRecord"
  926. ></product-list>
  927. <head-list ref="headRef" @changeParent="changeAnswer"></head-list>
  928. <ProductionVersion
  929. ref="versionRefs"
  930. @changeProduct="changeProduct"
  931. ></ProductionVersion>
  932. <taskinstance-dialog
  933. ref="taskinstanceDialogRef"
  934. v-if="taskinstanceDialogFlag"
  935. @saveTaskInstance="saveTaskInstance"
  936. :visible.sync="taskinstanceDialogFlag"
  937. ></taskinstance-dialog>
  938. <timeDialog
  939. @chooseTime="chooseTime"
  940. ref="timeDialogRef"
  941. :isBatch="true"
  942. ></timeDialog>
  943. <selectStockLedgerDialog
  944. ref="selectStockLedgerDialogRef"
  945. @changeParent="replaceTable"
  946. :isSupplier="isSupplier"
  947. ></selectStockLedgerDialog>
  948. <commodityPriceListDialog
  949. ref="commodityPriceListDialogRef"
  950. @changeParent="changeParent"
  951. ></commodityPriceListDialog>
  952. </el-form>
  953. </template>
  954. <script>
  955. import { numberReg } from 'ele-admin';
  956. import productList from '@/BIZComponents/product-list.vue';
  957. import dictMixins from '@/mixins/dictMixins';
  958. import fileUpload from '@/components/upload/fileUpload';
  959. import headList from '@/BIZComponents/user-select/user-select.vue';
  960. import ProductionVersion from '@/components/ProductionVersion2/index.vue';
  961. import { getInventoryTotalAPI } from '@/api/wms';
  962. import { pricingWayList, lbjtList } from '@/enum/dict.js';
  963. import { changeCount, getAllPrice, getAllDiscountPrice, formatPrice } from '@/BIZComponents/setProduct.js';
  964. import { contactQueryByCategoryIdsAPI } from '@/api/saleManage/contact';
  965. import taskinstanceDialog from '@/BIZComponents/procedure/taskinstanceDialog.vue';
  966. import timeDialog from '@/components/timeDialog/index.vue';
  967. import { copyObj } from '@/utils/util';
  968. import selectStockLedgerDialog from '@/BIZComponents/selectStockLedger/selectStockLedgerDialog.vue'; //库存台账
  969. import setAllValue from '@/BIZComponents/setAllValue.vue'; //批量修改
  970. import tabMixins from '@/mixins/tableColumnsMixin';
  971. import commodityPriceListDialog from '@/views/commodityManagement/commodityPriceList/components/commodityPriceListDialog.vue';
  972. const dayjs = require('dayjs');
  973. import { levelList, quoteTypeOp } from '@/enum/dict.js';
  974. import {
  975. getGoodsPriceByCondition,
  976. getGoodsByCategoryId
  977. } from '@/api/goodsManage/index';
  978. import { parameterGetByCode } from '@/api/main/index.js';
  979. import { getSummaries } from '@/utils/util.js';
  980. export default {
  981. mixins: [dictMixins, tabMixins],
  982. components: {
  983. fileUpload,
  984. productList,
  985. headList,
  986. ProductionVersion,
  987. taskinstanceDialog,
  988. timeDialog,
  989. selectStockLedgerDialog,
  990. commodityPriceListDialog,
  991. setAllValue
  992. },
  993. props: {
  994. pageName: {
  995. default: '',
  996. type: String
  997. },
  998. isDiscountTotalPrice: {
  999. default: false,
  1000. type: Boolean
  1001. },
  1002. quoteType: {
  1003. type: Number,
  1004. default: 1
  1005. },
  1006. isGuaranteePeriod: {
  1007. default: true,
  1008. type: Boolean
  1009. },
  1010. customerMark: {
  1011. default: '',
  1012. type: String
  1013. },
  1014. isContractId: {
  1015. type: Boolean,
  1016. default: false
  1017. },
  1018. isSinglePrice: {
  1019. //单价必填
  1020. type: Boolean,
  1021. default: true
  1022. },
  1023. isTotalCount: {
  1024. //数量必填
  1025. type: Boolean,
  1026. default: true
  1027. },
  1028. isCustomerMark: {
  1029. //客户代号必填
  1030. type: Boolean,
  1031. default: false
  1032. },
  1033. isDiscount: {
  1034. //折让
  1035. type: Boolean,
  1036. default: true
  1037. },
  1038. isProduceDeliveryDeadline: {
  1039. //生产交付交期必填
  1040. type: Boolean,
  1041. default: false
  1042. },
  1043. isDrawer: {
  1044. type: Boolean,
  1045. default: false
  1046. },
  1047. isChangeCount: {
  1048. //默认计算
  1049. type: Boolean,
  1050. default: true
  1051. },
  1052. contractBookType: {
  1053. //合同类型 1销售 2采购
  1054. type: [String, Number],
  1055. default: 1
  1056. },
  1057. isTemporary: {
  1058. //临时
  1059. type: Boolean,
  1060. default: false
  1061. },
  1062. isSupplier: {
  1063. //供应商
  1064. type: Boolean,
  1065. default: false
  1066. },
  1067. isSalesRecord: {
  1068. default: ''
  1069. },
  1070. isArrivalWay: {
  1071. //分批到货时间
  1072. type: Boolean,
  1073. default: false
  1074. },
  1075. //订单类型
  1076. needProduce: {
  1077. type: [String, Number],
  1078. default: 1
  1079. },
  1080. cacheKeyUrl: '',
  1081. //是否显示订单编码
  1082. isOrderNo: {
  1083. type: Boolean,
  1084. default: false
  1085. },
  1086. isBatchNo: {
  1087. type: Boolean, //批次号是否必填
  1088. default: false
  1089. },
  1090. orderOption: {
  1091. default: () => {
  1092. return [];
  1093. }
  1094. },
  1095. //是否商品
  1096. isGoods: {
  1097. type: Boolean,
  1098. default: false
  1099. },
  1100. // 是否税率必填
  1101. isTaxRate: {
  1102. type: [Number, String],
  1103. default: 0
  1104. },
  1105. defTaxRate: {
  1106. type: Number,
  1107. default: undefined
  1108. },
  1109. //是否显示增重重量
  1110. isIncreaseTotalWeight: {
  1111. type: Boolean,
  1112. default: false
  1113. },
  1114. countObj: {
  1115. type: Object,
  1116. default: () => {
  1117. return {
  1118. countKey: 'saleCount',
  1119. unitKey: 'saleUnit',
  1120. unitIdKey: 'saleUnitId'
  1121. };
  1122. }
  1123. },
  1124. showSummary: {
  1125. type: Boolean,
  1126. default: false
  1127. }
  1128. },
  1129. data() {
  1130. const defaultForm = {
  1131. key: null,
  1132. endTime: '',
  1133. isFirst: 0,
  1134. name: '',
  1135. startTime: '',
  1136. workHour: '',
  1137. guaranteePeriodUnitCode: '',
  1138. technicalDrawings: [],
  1139. arrivalWay: 1,
  1140. // 生产加工类型特有字段
  1141. thickNess: '',
  1142. squareNumber: '',
  1143. processingFeeBeforeTax: '',
  1144. packagingFeeNotTaxed: '',
  1145. transportationFeeWithoutTax: '',
  1146. extraTax: '',
  1147. quotationSubtotalTax: '',
  1148. // 新增未税小记字段
  1149. quotationSubtotalBeforeTax: '',
  1150. quoteWay: 1,
  1151. discountRatio: 100
  1152. };
  1153. return {
  1154. levelList,
  1155. taskinstanceDialogFlag: false,
  1156. allPrice: 0,
  1157. numberReg,
  1158. defaultForm,
  1159. form: {
  1160. datasource: [],
  1161. discountTotalPrice: 0
  1162. },
  1163. isDate: 1,
  1164. pricingWayList,
  1165. curIndex: '',
  1166. rules: {},
  1167. dictList: {},
  1168. arrivalWayList: [
  1169. { label: '一次性到货', value: 1 },
  1170. { label: '分批到货', value: 2 }
  1171. ],
  1172. columnsVersion: 1,
  1173. selection: [],
  1174. quoteTypeOp
  1175. };
  1176. },
  1177. computed: {
  1178. canHandl() {
  1179. return this.form.datasource.length;
  1180. },
  1181. columns() {
  1182. let columnsVersion = this.columnsVersion;
  1183. // 基础列定义
  1184. let baseColumns = [
  1185. {
  1186. width: 65,
  1187. type: 'index',
  1188. columnKey: 'index',
  1189. align: 'center',
  1190. fixed: 'left'
  1191. },
  1192. {
  1193. label: '选择',
  1194. width: 45,
  1195. type: 'selection',
  1196. columnKey: 'selection',
  1197. align: 'center',
  1198. fixed: 'left'
  1199. },
  1200. {
  1201. minWidth: 200,
  1202. prop: 'orderNo',
  1203. slot: 'orderNo',
  1204. label: '订单编码',
  1205. isNone: !this.isOrderNo,
  1206. showOverflowTooltip: true,
  1207. align: 'center'
  1208. },
  1209. {
  1210. width: 280,
  1211. prop: 'productName',
  1212. label: '名称',
  1213. slot: 'productName',
  1214. headerSlot: 'headerProductName',
  1215. align: 'center',
  1216. },
  1217. {
  1218. width: 120,
  1219. prop: 'productCode',
  1220. label: '编码',
  1221. slot: 'productCode',
  1222. align: 'center'
  1223. },
  1224. {
  1225. width: 120,
  1226. prop: 'specification',
  1227. label: '规格',
  1228. slot: 'specification',
  1229. align: 'center'
  1230. },
  1231. {
  1232. minWidth: 240,
  1233. prop: 'taskName',
  1234. label: '工序',
  1235. slot: 'taskName',
  1236. align: 'center'
  1237. },
  1238. {
  1239. minWidth: 120,
  1240. prop: 'entrustedEnterpriseId',
  1241. label: '受托企业',
  1242. slot: 'entrustedEnterpriseId',
  1243. isNone: !this.isCustomerMark,
  1244. align: 'center'
  1245. },
  1246. {
  1247. width: 140,
  1248. prop: 'pricingWay',
  1249. label: '计价方式',
  1250. headerSlot: 'headerPricingWay',
  1251. slot: 'pricingWay',
  1252. isNone: this.quoteType === 2,
  1253. fixed: 'left',
  1254. align: 'center'
  1255. },
  1256. {
  1257. width: 250,
  1258. prop: 'saleCount',
  1259. label: '数量',
  1260. slot: 'saleCount',
  1261. headerSlot: this.isTotalCount ? 'headerTotalCount' : '',
  1262. align: 'center'
  1263. },
  1264. {
  1265. width: 250,
  1266. prop: 'quoteWay',
  1267. label: '报价方式',
  1268. slot: 'quoteWay',
  1269. headerSlot: 'headerQuoteWay',
  1270. align: 'center'
  1271. },
  1272. ];
  1273. // 当quoteType为2时添加生产加工相关列
  1274. if (this.quoteType === 2) {
  1275. baseColumns.push(
  1276. {
  1277. width: 150,
  1278. prop: 'thickNess',
  1279. label: '厚度',
  1280. slot: 'thickNess',
  1281. align: 'center'
  1282. },
  1283. {
  1284. width: 150,
  1285. prop: 'squareNumber',
  1286. label: '平方数',
  1287. slot: 'squareNumber',
  1288. align: 'center'
  1289. },
  1290. {
  1291. width: 150,
  1292. prop: 'processingFeeBeforeTax',
  1293. label: '加工费(未税)',
  1294. slot: 'processingFeeBeforeTax',
  1295. align: 'center'
  1296. },
  1297. {
  1298. width: 150,
  1299. prop: 'packagingFeeNotTaxed',
  1300. label: '包装费(未税)',
  1301. slot: 'packagingFeeNotTaxed',
  1302. align: 'center'
  1303. },
  1304. {
  1305. width: 150,
  1306. prop: 'transportationFeeWithoutTax',
  1307. label: '运输费(未税)',
  1308. slot: 'transportationFeeWithoutTax',
  1309. align: 'center'
  1310. },
  1311. {
  1312. width: 150,
  1313. prop: 'quotationSubtotalBeforeTax',
  1314. label: '未税小计',
  1315. slot: 'additionalTaxRate_untaxed',
  1316. align: 'center'
  1317. },
  1318. {
  1319. width: 150,
  1320. prop: 'extraTax',
  1321. label: '税率(%)',
  1322. slot: 'extraTax',
  1323. align: 'center'
  1324. },
  1325. {
  1326. width: 150,
  1327. prop: 'quotationSubtotalTax',
  1328. label: '含税小计',
  1329. slot: 'quotationSubtotalTax',
  1330. align: 'center'
  1331. }
  1332. );
  1333. }
  1334. // 其他列
  1335. const otherColumns = [
  1336. {
  1337. width: 160,
  1338. prop: 'customerExpectDeliveryDeadline',
  1339. label: this.contractBookType == 1 ? '客户期望交期' : '交付日期',
  1340. slot: 'customerExpectDeliveryDeadline',
  1341. headerSlot:
  1342. this.isDate == 1 && this.quoteType != 2
  1343. ? 'headerCustomerExpectDeliveryDeadline'
  1344. : '',
  1345. align: 'center'
  1346. },
  1347. {
  1348. width: 180,
  1349. prop: 'singleWeight',
  1350. label: '单重',
  1351. slot: 'singleWeight',
  1352. headerSlot: 'headerSingleWeight',
  1353. align: 'center'
  1354. },
  1355. {
  1356. minWidth: 120,
  1357. prop: 'goodsLevel',
  1358. label: '物品级别',
  1359. slot: 'goodsLevel',
  1360. align: 'center',
  1361. isNone: this.quoteType === 2
  1362. },
  1363. {
  1364. width: 200,
  1365. prop: 'totalCount',
  1366. label: '计量数量',
  1367. headerSlot: 'headerTotalCount',
  1368. align: 'center',
  1369. formatter: (_row, _column, cellValue) => {
  1370. if (_row.totalCount) {
  1371. return _row.totalCount + ' ' + (_row.measuringUnit || '');
  1372. }
  1373. },
  1374. isNone: this.quoteType === 2
  1375. },
  1376. {
  1377. width: 200,
  1378. prop: 'customerMark',
  1379. label: this.contractBookType == 1 ? '客户代号' : '供应商代号',
  1380. slot: 'customerMark',
  1381. headerSlot: this.isCustomerMark ? 'headerCustomerMark' : '',
  1382. align: 'center',
  1383. isNone: this.quoteType === 2
  1384. },
  1385. {
  1386. minWidth: 160,
  1387. prop: 'productionCodes',
  1388. label: '生产编号',
  1389. align: 'center',
  1390. isNone: this.quoteType === 2
  1391. },
  1392. {
  1393. minWidth: 280,
  1394. prop: 'productionRequirements',
  1395. label: '生产要求',
  1396. align: 'center',
  1397. slot: 'productionRequirements',
  1398. isNone: !this.isProductionRequirements && this.quoteType === 2
  1399. },
  1400. {
  1401. width: 200,
  1402. prop: 'productCategoryName',
  1403. label: '类型',
  1404. slot: 'productCategoryName',
  1405. align: 'center',
  1406. isNone: this.quoteType === 2
  1407. },
  1408. {
  1409. width: 120,
  1410. prop: 'packingSpecification',
  1411. align: 'center',
  1412. label: '包装规格',
  1413. showOverflowTooltip: true,
  1414. isNone: this.quoteType === 2
  1415. },
  1416. {
  1417. width: 160,
  1418. prop: 'goodsPriceType',
  1419. label: '价格类型',
  1420. slot: 'goodsPriceType',
  1421. align: 'center',
  1422. isNone: this.quoteType === 2
  1423. },
  1424. {
  1425. width: 200,
  1426. prop: 'singlePrice',
  1427. label: '单价',
  1428. slot: 'singlePrice',
  1429. headerSlot: this.isSinglePrice ? 'headerSinglePrice' : '',
  1430. align: 'center',
  1431. isNone: this.quoteType === 2
  1432. },
  1433. {
  1434. width: 160,
  1435. prop: 'taxRate',
  1436. label: '税率',
  1437. slot: 'taxRate',
  1438. align: 'center',
  1439. headerSlot: this.isTaxRate == 1 ? 'headerTaxRate' : '',
  1440. isNone: this.quoteType === 2
  1441. },
  1442. {
  1443. width: 180,
  1444. prop: 'notaxSinglePrice',
  1445. label: '不含税单价',
  1446. slot: 'notaxSinglePrice',
  1447. align: 'center',
  1448. isNone: this.quoteType === 2
  1449. },
  1450. {
  1451. width: 160,
  1452. prop: 'discountRatio',
  1453. label: '折让比例',
  1454. align: 'center',
  1455. isNone: !this.isDiscount,
  1456. slot: 'discountRatio',
  1457. headerSlot: 'headerDiscountRatio'
  1458. },
  1459. {
  1460. width: 160,
  1461. prop: 'discountSinglePrice',
  1462. label: '折让单价',
  1463. align: 'center',
  1464. isNone: !this.isDiscount,
  1465. formatter: (_row, _column, cellValue) => {
  1466. return _row.discountSinglePrice
  1467. ? formatPrice(Number(_row.discountSinglePrice))
  1468. : '';
  1469. }
  1470. },
  1471. {
  1472. width: 120,
  1473. prop: 'totalPrice',
  1474. label: '合计',
  1475. slot: 'totalPrice',
  1476. align: 'center'
  1477. },
  1478. {
  1479. width: 160,
  1480. prop: 'discountTotalPrice',
  1481. label: '折让合计',
  1482. align: 'center',
  1483. isNone: !this.isDiscount,
  1484. formatter: (_row, _column, cellValue) => {
  1485. return _row.discountTotalPrice
  1486. ? formatPrice(Number(_row.discountTotalPrice))
  1487. : '';
  1488. }
  1489. },
  1490. {
  1491. width: 110,
  1492. prop: 'batchNo',
  1493. label: '批次号',
  1494. slot: 'batchNo',
  1495. headerSlot: this.isBatchNo ? 'headerBatchNo' : '',
  1496. align: 'center',
  1497. isNone: this.quoteType === 2
  1498. },
  1499. {
  1500. width: 120,
  1501. prop: 'availableCountBase',
  1502. label: '库存数量',
  1503. slot: 'availableCountBase',
  1504. align: 'center',
  1505. isNone: this.quoteType === 2
  1506. },
  1507. {
  1508. prop: 'provenance',
  1509. label: '产地',
  1510. slot: 'provenance',
  1511. align: 'center',
  1512. showOverflowTooltip: true,
  1513. minWidth: 200,
  1514. isNone: this.quoteType === 2
  1515. },
  1516. {
  1517. width: 180,
  1518. prop: 'totalWeight',
  1519. label: '总重',
  1520. slot: 'totalWeight',
  1521. formatter: (_row, _column, cellValue) => {
  1522. if (_row.totalWeight) {
  1523. return _row.totalWeight + ' ' + (_row.weightUnit || '');
  1524. }
  1525. },
  1526. align: 'center'
  1527. },
  1528. {
  1529. width: 180,
  1530. prop: 'increaseTotalWeight',
  1531. label: '增重重量',
  1532. slot: 'increaseTotalWeight',
  1533. isNone: this.quoteType === 2 || !this.isIncreaseTotalWeight,
  1534. align: 'center'
  1535. },
  1536. {
  1537. width: 160,
  1538. prop: 'productBrand',
  1539. label: '牌号',
  1540. slot: 'productBrand',
  1541. align: 'center',
  1542. isNone: this.quoteType === 2
  1543. },
  1544. {
  1545. width: 120,
  1546. prop: 'modelType',
  1547. label: '型号',
  1548. slot: 'modelType',
  1549. align: 'center',
  1550. isNone: this.quoteType === 2
  1551. },
  1552. {
  1553. width: 160,
  1554. prop: 'modelKey',
  1555. label: '机型',
  1556. slot: 'modelKey',
  1557. align: 'center',
  1558. isNone: this.quoteType === 2
  1559. },
  1560. {
  1561. width: 160,
  1562. prop: 'colorKey',
  1563. label: '颜色',
  1564. slot: 'colorKey',
  1565. align: 'center',
  1566. isNone: this.quoteType === 2
  1567. },
  1568. {
  1569. width: 120,
  1570. prop: 'produceType',
  1571. align: 'center',
  1572. label: '属性类型',
  1573. isNone: this.quoteType === 2,
  1574. showOverflowTooltip: true,
  1575. formatter: (row, column) => {
  1576. if (row.produceType) {
  1577. return row.produceType
  1578. .map((item) => {
  1579. return lbjtList[item];
  1580. })
  1581. .toString();
  1582. }
  1583. }
  1584. },
  1585. {
  1586. width: 160,
  1587. prop: 'arrivalWay',
  1588. label: '到货方式',
  1589. slot: 'arrivalWay',
  1590. align: 'center',
  1591. isNone: !this.isArrivalWay || this.quoteType === 2
  1592. },
  1593. {
  1594. width: 160,
  1595. prop: 'produceDeliveryDeadline',
  1596. label: '生产交付交期',
  1597. slot: 'produceDeliveryDeadline',
  1598. headerSlot:
  1599. this.isDate == 1 && this.isProduceDeliveryDeadline
  1600. ? 'headerProduceDeliveryDeadline'
  1601. : '',
  1602. isNone: this.contractBookType != 1,
  1603. align: 'center'
  1604. },
  1605. {
  1606. width: 200,
  1607. prop: 'guaranteePeriod',
  1608. label: '有效期',
  1609. slot: 'guaranteePeriod',
  1610. align: 'center',
  1611. isNone: this.quoteType === 2
  1612. },
  1613. {
  1614. width: 200,
  1615. prop: 'guaranteePeriodDeadline',
  1616. label: '有效期截止日期',
  1617. slot: 'guaranteePeriodDeadline',
  1618. isNone: !this.isGuaranteePeriod || this.quoteType === 2,
  1619. align: 'center'
  1620. },
  1621. {
  1622. width: 120,
  1623. prop: 'imgCode',
  1624. align: 'center',
  1625. label: '图号/件号',
  1626. showOverflowTooltip: true,
  1627. isNone: this.quoteType === 2
  1628. },
  1629. {
  1630. width: 220,
  1631. prop: 'customerReqFiles',
  1632. label: '客户需求',
  1633. slot: 'customerReqFiles',
  1634. align: 'center',
  1635. isNone: this.quoteType === 2
  1636. },
  1637. {
  1638. width: 130,
  1639. prop: 'technicalAnswerName',
  1640. label: '技术答疑人',
  1641. slot: 'technicalAnswerName',
  1642. align: 'center',
  1643. isNone: this.quoteType === 2
  1644. },
  1645. {
  1646. width: 220,
  1647. prop: 'technicalParams',
  1648. label: '技术参数',
  1649. slot: 'technicalParams',
  1650. align: 'center',
  1651. isNone: this.quoteType === 2
  1652. },
  1653. {
  1654. width: 240,
  1655. prop: 'technicalDrawings',
  1656. label: '技术图纸',
  1657. slot: 'technicalDrawings',
  1658. align: 'center'
  1659. },
  1660. {
  1661. width: 120,
  1662. prop: 'drawingVersion',
  1663. label: '图纸版本',
  1664. align: 'center',
  1665. isNone: this.quoteType === 2
  1666. },
  1667. {
  1668. width: 240,
  1669. prop: 'technologyRouteName',
  1670. label: '工艺路线',
  1671. slot: 'technologyRouteName',
  1672. align: 'center',
  1673. isNone: this.quoteType === 2
  1674. },
  1675. {
  1676. width: 240,
  1677. prop: 'industryArtFiles',
  1678. label: '工艺附件',
  1679. slot: 'industryArtFiles',
  1680. align: 'center',
  1681. isNone: this.quoteType === 2
  1682. },
  1683. {
  1684. width: 240,
  1685. prop: 'otherFiles',
  1686. label: '其他附件',
  1687. slot: 'otherFiles',
  1688. align: 'center',
  1689. isNone: this.quoteType === 2
  1690. },
  1691. {
  1692. width: 220,
  1693. prop: 'remark',
  1694. label: '备注',
  1695. slot: 'remark',
  1696. align: 'center'
  1697. },
  1698. {
  1699. columnKey: 'action',
  1700. label: '操作',
  1701. width: 120,
  1702. align: 'center',
  1703. resizable: false,
  1704. slot: 'action',
  1705. fixed: 'right',
  1706. showOverflowTooltip: true
  1707. }
  1708. ];
  1709. // 合并所有列
  1710. return [...baseColumns, ...otherColumns].filter((item) => !item.isNone);
  1711. }
  1712. },
  1713. created() {
  1714. parameterGetByCode({
  1715. code: 'eom_inventoryTable_customerExpectDeliveryDeadline'
  1716. }).then((res) => {
  1717. if (res.value) {
  1718. this.isDate = res.value;
  1719. }
  1720. });
  1721. },
  1722. methods: {
  1723. formatPrice,
  1724. getSummaries(param) {
  1725. return getSummaries(
  1726. param,
  1727. ['saleCount'],
  1728. ' '
  1729. );
  1730. },
  1731. handleCountChange(row, index,weightType) {
  1732. // 数量变化时,若为生产加工类型,触发含税小计计算
  1733. if (this.quoteType === 2) {
  1734. this.calculateIncludingTaxPrice(row, index);
  1735. } else {
  1736. this.changeCount(row, index,weightType);
  1737. }
  1738. },
  1739. packingChange(item, index) {
  1740. this.$set(
  1741. this.form.datasource[index],
  1742. this.countObj.unitKey,
  1743. item.conversionUnit
  1744. );
  1745. this.handleCountChange(this.form.datasource[index], index);
  1746. },
  1747. openVersion(index) {
  1748. this.$refs.versionRefs.open(index);
  1749. },
  1750. //设置分批到货时间
  1751. handleMethod(row, index) {
  1752. this.$refs.timeDialogRef.open(row, index);
  1753. },
  1754. chooseTime({ arrivalBatch, index }) {
  1755. this.$set(
  1756. this.form.datasource[index],
  1757. 'arrivalBatch',
  1758. copyObj(arrivalBatch)
  1759. );
  1760. },
  1761. //工艺路线
  1762. changeProduct(data, index) {
  1763. this.$set(
  1764. this.form.datasource[index],
  1765. 'technologyRouteName',
  1766. data.name
  1767. );
  1768. this.$set(this.form.datasource[index], 'technologyRouteId', data.id);
  1769. },
  1770. handleTaskinstance(row, index) {
  1771. this.taskinstanceDialogFlag = true;
  1772. this.$nextTick(() => {
  1773. this.$refs.taskinstanceDialogRef.open(row, index);
  1774. });
  1775. },
  1776. saveTaskInstance(row = {}) {
  1777. this.$set(this.form.datasource[row.index], 'taskId', row.id);
  1778. this.$set(this.form.datasource[row.index], 'taskName', row.name);
  1779. this.$set(
  1780. this.form.datasource[row.index],
  1781. 'routingId',
  1782. row.produceRoutingId
  1783. );
  1784. },
  1785. async getSupplierObj(productList, queryName) {
  1786. try {
  1787. let categoryIds = productList
  1788. .filter((item) => item.productId)
  1789. .map((item) => item.productId);
  1790. if (categoryIds.length > 0) {
  1791. return await contactQueryByCategoryIdsAPI({
  1792. categoryIds
  1793. });
  1794. } else {
  1795. return Promise.resolve({});
  1796. }
  1797. } catch (e) {
  1798. return Promise.resolve({});
  1799. }
  1800. },
  1801. setDeliveryDays(row, index, type, isAll) {
  1802. if (isAll) {
  1803. this.form.datasource.forEach((item, i) => {
  1804. let guaranteePeriodUnitName = this.guaranteePeriodUnit(
  1805. item.guaranteePeriodUnitCode
  1806. );
  1807. this.$set(
  1808. this.form.datasource[i],
  1809. 'guaranteePeriodDeadline',
  1810. guaranteePeriodUnitName != 'second'
  1811. ? this.setDay(
  1812. item.guaranteePeriod,
  1813. guaranteePeriodUnitName,
  1814. item
  1815. )
  1816. : ''
  1817. );
  1818. });
  1819. return;
  1820. }
  1821. if (type == 'guaranteePeriod') {
  1822. let guaranteePeriodUnitName = this.guaranteePeriodUnit(
  1823. row.guaranteePeriodUnitCode
  1824. );
  1825. this.$set(
  1826. this.form.datasource[index],
  1827. 'guaranteePeriodDeadline',
  1828. guaranteePeriodUnitName != 'second'
  1829. ? this.setDay(row.guaranteePeriod, guaranteePeriodUnitName, row)
  1830. : ''
  1831. );
  1832. }
  1833. },
  1834. guaranteePeriodUnit(code) {
  1835. return code == 3
  1836. ? 'day'
  1837. : code == 4
  1838. ? 'month'
  1839. : code == 5
  1840. ? 'year'
  1841. : 'second';
  1842. },
  1843. setDay(addDay, dateType = 'day', item) {
  1844. let tiem =
  1845. this.contractBookType == 1
  1846. ? item.produceDeliveryDeadline
  1847. : item.customerExpectDeliveryDeadline;
  1848. return dayjs(tiem || new Date())
  1849. .add(addDay, dateType)
  1850. .format('YYYY-MM-DD');
  1851. },
  1852. // 返回列表数据
  1853. getTableValue() {
  1854. let comitDatasource = copyObj(this.form.datasource);
  1855. if (comitDatasource.length === 0) return [];
  1856. comitDatasource.forEach((v) => {
  1857. if (v.guaranteePeriodUnitCode) {
  1858. v.guaranteePeriodUnitName = this.getDictValue(
  1859. '保质期单位',
  1860. v.guaranteePeriodUnitCode
  1861. );
  1862. }
  1863. if (v.modelKey) {
  1864. v.modelKey = v.modelKey.toString();
  1865. }
  1866. if (v.colorKey) {
  1867. v.colorKey = v.colorKey.toString();
  1868. }
  1869. v.technicalDrawings = v.technicalDrawings ? v.technicalDrawings : [];
  1870. v.customerReqFiles = v.customerReqFiles || [];
  1871. v.industryArtFiles = v.industryArtFiles || [];
  1872. v.otherFiles = v.otherFiles || [];
  1873. });
  1874. return comitDatasource;
  1875. },
  1876. getPrice() {
  1877. return [this.allPrice, this.form.discountTotalPrice];
  1878. },
  1879. //改变数量
  1880. changeCount(row, index, weightType) {
  1881. if (!row) {
  1882. this.form.datasource = this.form.datasource.map((item, i) => {
  1883. return changeCount(item, this.countObj, false);
  1884. });
  1885. this.form.datasource.forEach((item, i) => {
  1886. this.setIncreaseTotalWeight(item, i);
  1887. });
  1888. } else {
  1889. const updatedRow = changeCount(row, this.countObj, false, weightType);
  1890. this.$set(this.form.datasource, index, updatedRow);
  1891. this.setIncreaseTotalWeight(row, index);
  1892. }
  1893. this.$nextTick(() => {
  1894. // 生产加工类型不需要计算不含税单价,但需要计算含税小计
  1895. this.getNotaxSinglePrice();
  1896. this.changeAll();
  1897. });
  1898. },
  1899. setIncreaseTotalWeight(row, index) {
  1900. if (row.pricingWay == 3) {
  1901. this.$set(
  1902. this.form.datasource[index],
  1903. 'totalPrice',
  1904. formatPrice((row.increaseTotalWeight || 0) * row.singlePrice)
  1905. );
  1906. this.changeAll();
  1907. }
  1908. },
  1909. // 计算含税小计(原含税单价逻辑)
  1910. calculateIncludingTaxPrice(row, index) {
  1911. if (!row) return;
  1912. // 计算未税小记
  1913. const quotationSubtotalBeforeTax =
  1914. (Number(row.processingFeeBeforeTax) || 0) +
  1915. (Number(row.packagingFeeNotTaxed) || 0) +
  1916. (Number(row.transportationFeeWithoutTax) || 0);
  1917. // 使用 $nextTick 确保响应式更新完成
  1918. // this.$nextTick(() => {
  1919. this.$set(
  1920. this.form.datasource[index],
  1921. 'quotationSubtotalBeforeTax',
  1922. quotationSubtotalBeforeTax.toFixed(2)
  1923. );
  1924. // 计算含税小计
  1925. const taxRate = (Number(row.extraTax) || 0) / 100;
  1926. const quotationSubtotalTax = quotationSubtotalBeforeTax * (1 + taxRate);
  1927. this.$set(
  1928. this.form.datasource[index],
  1929. 'quotationSubtotalTax',
  1930. quotationSubtotalTax.toFixed(2)
  1931. );
  1932. const quantity = Number(row[this.countObj.countKey]) || 1;
  1933. const totalPrice = quotationSubtotalTax * quantity;
  1934. this.$set(
  1935. this.form.datasource[index],
  1936. 'totalPrice',
  1937. formatPrice(totalPrice)
  1938. );
  1939. if (
  1940. row[this.countObj.unitKey] == row.weightUnit &&
  1941. row.pricingWay == 1
  1942. ) {
  1943. this.$set(this.form.datasource[index], 'totalWeight', quantity);
  1944. } else {
  1945. if (quantity && row.singleWeight) {
  1946. this.$set(
  1947. this.form.datasource[index],
  1948. 'totalWeight',
  1949. (quantity * row.singleWeight).toFixed(2)
  1950. );
  1951. }
  1952. }
  1953. this.changeAll();
  1954. // });
  1955. },
  1956. changeAll() {
  1957. this.allPrice = getAllPrice(this.form.datasource) || 0;
  1958. this.form.discountTotalPrice = getAllDiscountPrice(this.form.datasource) || 0;
  1959. if (this.isDiscountTotalPrice) {
  1960. this.form.discountTotalPrice = this.form.discountTotalPrice;
  1961. this.$emit('setDiscountTotalPrice', this.form.discountTotalPrice);
  1962. }
  1963. this.$emit('setCountAmount', this.allPrice, this.form.discountTotalPrice);
  1964. },
  1965. setCustomerMark(customerMark) {
  1966. this.form.datasource.forEach((item) => {
  1967. item['customerMark'] = customerMark;
  1968. this.$forceUpdate();
  1969. });
  1970. },
  1971. // 计算折让单价,折让总价
  1972. getDiscountRatioPrice(row) {
  1973. this.form.datasource.forEach((item, index) => {
  1974. if (item.singlePrice && item.discountRatio) {
  1975. this.$set(
  1976. this.form.datasource[index],
  1977. 'discountSinglePrice',
  1978. formatPrice(item.singlePrice * (item.discountRatio / 100))
  1979. );
  1980. this.$set(
  1981. this.form.datasource[index],
  1982. 'discountTotalPrice',
  1983. formatPrice(
  1984. item.totalPrice * (item.discountRatio / 100)
  1985. )
  1986. );
  1987. } else {
  1988. this.$set(this.form.datasource[index], 'discountSinglePrice', 0);
  1989. this.$set(this.form.datasource[index], 'discountTotalPrice', 0);
  1990. }
  1991. this.$set(
  1992. this.form,
  1993. 'discountTotalPrice',
  1994. this.form.datasource.reduce(
  1995. (acc, cur) => acc + Number(cur.discountTotalPrice || 0),
  1996. 0
  1997. )
  1998. );
  1999. this.changeAll();
  2000. });
  2001. },
  2002. //计算不含税单价
  2003. getNotaxSinglePrice() {
  2004. this.form.datasource.forEach((item, index) => {
  2005. if (item.singlePrice && item.taxRate) {
  2006. this.$set(
  2007. this.form.datasource[index],
  2008. 'notaxSinglePrice',
  2009. formatPrice(item.singlePrice / (1 + item.taxRate / 100))
  2010. );
  2011. } else {
  2012. this.$set(this.form.datasource[index], 'notaxSinglePrice', '');
  2013. }
  2014. });
  2015. },
  2016. //设置优惠后总金额修改产品单价
  2017. discountInputByOrder(val) {
  2018. this.form.discountTotalPrice = val;
  2019. this.form.datasource.forEach((item, index) => {
  2020. this.$set(
  2021. this.form.datasource[index],
  2022. 'discountSinglePrice',
  2023. this.getDiscountSinglePrice(item)
  2024. );
  2025. this.$set(
  2026. this.form.datasource[index],
  2027. 'discountTotalPrice',
  2028. this.getDiscountTotalPrice(item)
  2029. );
  2030. this.$set(
  2031. this.form.datasource[index],
  2032. 'discountRatio',
  2033. this.getDiscountRatio(item)
  2034. );
  2035. });
  2036. this.$emit('setDiscountTotalPrice', val);
  2037. this.$forceUpdate();
  2038. this.$refs.table.reRenderTable();
  2039. },
  2040. setAllValueChange({ key, value }) {
  2041. let indexS = this.selection.map((item) => item.key - 1);
  2042. indexS.forEach((i) => {
  2043. this.$set(this.form.datasource[i], key, value);
  2044. this.setDeliveryDays(this.form.datasource[i], i, 'guaranteePeriod');
  2045. });
  2046. },
  2047. //获取折让单价
  2048. getDiscountSinglePrice(row) {
  2049. let num =
  2050. (Number(this.form.discountTotalPrice) / Number(this.allPrice)) *
  2051. Number(row.singlePrice);
  2052. return isNaN(num) ? '' : formatPrice(num);
  2053. },
  2054. //获取折让比例
  2055. getDiscountRatio(row) {
  2056. let num = 100;
  2057. // if(Number(row.discountRatio)) {
  2058. // num =
  2059. // ((Number(this.form.discountTotalPrice) / Number(this.allPrice)) * Number(row.discountRatio)).toFixed(2);
  2060. // console.log('折让比例', row.discountRatio, num, (Number(this.form.discountTotalPrice) / Number(this.allPrice)))
  2061. // } else {
  2062. num = ((Number(this.form.discountTotalPrice) / Number(this.allPrice)) * 100).toFixed(2);
  2063. // }
  2064. return isNaN(num) ? '' : num;
  2065. },
  2066. //获取折让合计
  2067. getDiscountTotalPrice(row) {
  2068. let num = 0;
  2069. num =
  2070. Number(row.discountSinglePrice) * Number(row[this.countObj.countKey]);
  2071. return isNaN(num) ? '' : formatPrice(num);
  2072. },
  2073. orderNoChange(row, item) {
  2074. row['orderId'] = item.orderId;
  2075. },
  2076. //修改回显
  2077. async putTableValue(data) {
  2078. let productList =
  2079. (data &&
  2080. (data.quoteProductList || data.productList || data.detailList)) ||
  2081. [];
  2082. if (productList) {
  2083. let supplierObj = await this.getSupplierObj(productList, 'productId');
  2084. productList.forEach((item, index) => {
  2085. item['key'] = index + 1;
  2086. if (item.modelKey) {
  2087. item.modelKey = item.modelKey.split(',');
  2088. }
  2089. if (item.colorKey) {
  2090. item.colorKey = item.colorKey.split(',');
  2091. }
  2092. item.guaranteePeriodUnitCode = item.guaranteePeriodUnitCode
  2093. ? item.guaranteePeriodUnitCode + ''
  2094. : '';
  2095. let guaranteePeriodUnitName = this.guaranteePeriodUnit(
  2096. item.guaranteePeriodUnitCode
  2097. );
  2098. if (item.guaranteePeriod && item.guaranteePeriodUnitCode) {
  2099. item['guaranteePeriodDeadline'] =
  2100. item['guaranteePeriodDeadline'] ||
  2101. guaranteePeriodUnitName != 'second'
  2102. ? this.setDay(
  2103. item.guaranteePeriod,
  2104. guaranteePeriodUnitName,
  2105. item
  2106. )
  2107. : '';
  2108. }
  2109. item.entrustedEnterpriseIdList = supplierObj[item.productId];
  2110. // if (supplierObj[item.productId]?.length === 1) {
  2111. // item.entrustedEnterpriseId = supplierObj[item.productId][0].id;
  2112. // }
  2113. // item.entrustedEnterpriseId = item.entrustedEnterpriseId || undefined;
  2114. this.$set(
  2115. item,
  2116. 'entrustedEnterpriseId',
  2117. item.entrustedEnterpriseId || ''
  2118. );
  2119. item['customerMark'] = item.customerMark || this.customerMark;
  2120. item['arrivalWay'] = item.arrivalWay || 1;
  2121. item.discountRatio = Number(item.discountRatio) || 100;
  2122. });
  2123. this.form.datasource = productList;
  2124. let codeList = this.form.datasource
  2125. .filter((item) => item.productCode)
  2126. .map((item) => item.productCode);
  2127. //获取仓库库存
  2128. let inventoryTotalList = await getInventoryTotalAPI(codeList);
  2129. this.form.datasource
  2130. .filter((item) => item.productCode)
  2131. .forEach((item, index) => {
  2132. let find =
  2133. inventoryTotalList.find(
  2134. (key) => key.code == item.productCode
  2135. ) || {};
  2136. this.form.datasource;
  2137. this.$set(
  2138. this.form.datasource[index],
  2139. 'availableCountBase',
  2140. find.availableCountBase
  2141. );
  2142. });
  2143. if (this.isChangeCount) {
  2144. this.changeCount();
  2145. } else {
  2146. this.allPrice = data.totalAmount || data?.contractVO?.totalPrice;
  2147. }
  2148. if (this.isDiscountTotalPrice) {
  2149. this.form.discountTotalPrice =
  2150. data.payAmount || data?.contractVO?.discountTotalPrice;
  2151. }
  2152. this.$refs.table.reload();
  2153. }
  2154. },
  2155. //选择产品
  2156. handParent(row, index) {
  2157. let item = {
  2158. id: row?.productCode
  2159. };
  2160. if (row?.goodsId) {
  2161. this.handGoods(index);
  2162. return;
  2163. }
  2164. if (this.needProduce == 1 || this.needProduce == 2) {
  2165. this.$refs.productListRef.open(item, index);
  2166. } else {
  2167. this.$refs.selectStockLedgerDialogRef.open(item, index);
  2168. }
  2169. },
  2170. handGoods(index) {
  2171. this.$refs.commodityPriceListDialogRef.open(index);
  2172. },
  2173. //选择技术人回调
  2174. changeAnswer(obj, idx) {
  2175. this.$set(this.form.datasource[idx], 'technicalAnswerId', obj.id);
  2176. this.$set(this.form.datasource[idx], 'technicalAnswerName', obj.name);
  2177. },
  2178. handHead(row, index) {
  2179. let item = {
  2180. id: row.technicalAnswerId
  2181. };
  2182. this.$refs.headRef.open(item, index);
  2183. },
  2184. //选择产品回调
  2185. changeParent(obj, idx) {
  2186. obj.forEach((item, index) => {
  2187. let i = idx == -1 ? index : idx;
  2188. let row = JSON.parse(JSON.stringify(this.defaultForm));
  2189. row.key = this.form.datasource.length + 1;
  2190. let parasm = idx == -1 ? row : this.form.datasource[i];
  2191. this.$set(parasm, 'productId', item.id);
  2192. this.$set(parasm, 'categoryName', item.name);
  2193. this.$set(parasm, 'productCategoryId', item.categoryLevelId);
  2194. this.$set(parasm, 'productBrand', item.brandNum);
  2195. this.$set(parasm, 'productCategoryName', item.categoryLevelPath);
  2196. this.$set(parasm, 'productCode', item.code);
  2197. this.$set(parasm, 'productName', item.name);
  2198. this.$set(parasm, 'modelType', item.modelType);
  2199. this.$set(parasm, 'availableCountBase', item.availableCountBase);
  2200. this.$set(parasm, 'measuringUnit', item.measuringUnit);
  2201. this.$set(parasm, 'specification', item.specification);
  2202. this.$set(parasm, 'weightUnit', item.weightUnit);
  2203. this.$set(parasm, 'singleWeight', item.netWeight);
  2204. this.$set(parasm, 'pricingWay', 1);
  2205. this.$set(parasm, 'goodsLevel', item.goodsLevel);
  2206. this.$set(parasm, 'guaranteePeriod', item.warrantyPeriod);
  2207. this.$set(
  2208. parasm,
  2209. 'customerExpectDeliveryDeadline',
  2210. dayjs(new Date()).format('YYYY-MM-DD')
  2211. );
  2212. if (item.modelKey) {
  2213. this.$set(parasm, 'modelKey', item.modelKey.split(','));
  2214. }
  2215. if (item.colorKey) {
  2216. this.$set(parasm, 'colorKey', item.colorKey.split(','));
  2217. }
  2218. if (this.defTaxRate) {
  2219. this.$set(parasm, 'taxRate', parasm.taxRate || this.defTaxRate);
  2220. }
  2221. this.$set(
  2222. parasm,
  2223. 'guaranteePeriodUnitCode',
  2224. item.warrantyPeriodUnit ? item.warrantyPeriodUnit + '' : ''
  2225. );
  2226. if (item.warrantyPeriod && item.warrantyPeriodUnit) {
  2227. this.$set(
  2228. parasm,
  2229. 'guaranteePeriodDeadline',
  2230. this.setDay(
  2231. item.warrantyPeriod,
  2232. this.guaranteePeriodUnit(item.warrantyPeriodUnit),
  2233. {}
  2234. )
  2235. );
  2236. }
  2237. this.$set(
  2238. parasm,
  2239. 'packageDispositionList',
  2240. item.packageDispositionList
  2241. );
  2242. if (item.packageDispositionList?.length) {
  2243. this.$set(
  2244. parasm,
  2245. this.countObj.unitIdKey,
  2246. item.packageDispositionList[0].id
  2247. );
  2248. this.$set(
  2249. parasm,
  2250. this.countObj.unitKey,
  2251. item.packageDispositionList[0].conversionUnit
  2252. );
  2253. }
  2254. this.$set(parasm, 'arrivalWay', item.arrivalWay || 1);
  2255. this.$set(parasm, 'imgCode', item.imgCode);
  2256. this.$set(parasm, 'produceType', item.componentAttribute);
  2257. if (this.isOrderNo) {
  2258. this.$set(parasm, 'orderNo', this.orderOption[0]?.orderNo);
  2259. this.$set(parasm, 'orderId', this.orderOption[0]?.orderId);
  2260. }
  2261. if (this.isGoods && item.goodsId) {
  2262. this.$set(parasm, 'goodsId', item.goodsId);
  2263. this.$set(parasm, 'goodsPriceId', item.goodsPriceId);
  2264. this.$set(parasm, 'goodsPriceType', item.goodsPriceType);
  2265. this.$set(parasm, 'singlePrice', item.singlePrice);
  2266. this.$set(parasm, 'notaxSinglePrice', item.notaxSinglePrice);
  2267. this.$set(parasm, 'taxRate', item.taxRate);
  2268. this.$set(parasm, 'discountSinglePrice', item.singlePrice);
  2269. this.$set(parasm, 'totalCount', '');
  2270. this.$set(parasm, 'discountRatio', item.discountRatio);
  2271. } else {
  2272. this.$set(parasm, 'singlePrice', parasm.singlePrice || 0);
  2273. this.$set(parasm, 'discountRatio', parasm.discountRatio || 100);
  2274. }
  2275. // 初始化生产加工特有字段及未税小记
  2276. // 当quoteType为2时,数量默认设置为1
  2277. if (this.quoteType === 2) {
  2278. this.processSetValue(parasm);
  2279. }
  2280. if (this.isSupplier) {
  2281. this.$set(
  2282. parasm,
  2283. 'entrustedEnterpriseIdList',
  2284. item.entrustedEnterpriseIdList
  2285. );
  2286. this.$set(
  2287. parasm,
  2288. 'entrustedEnterpriseId',
  2289. item.entrustedEnterpriseId
  2290. );
  2291. }
  2292. this.$set(parasm, 'approvalNumber', item.extField?.approvalNumber);
  2293. this.$set(
  2294. parasm,
  2295. 'packingSpecification',
  2296. item.extField.packingSpecification
  2297. );
  2298. this.$set(parasm, 'customerMark', this.customerMark);
  2299. if (item.purchaseOrigins?.length > 0) {
  2300. item.purchaseOrigins = item.purchaseOrigins.map((val) => val + '');
  2301. }
  2302. this.$set(parasm, 'provenance', item.purchaseOrigins || []);
  2303. if (idx == -1) {
  2304. this.form.datasource.push(row);
  2305. }
  2306. });
  2307. this.changeCount();
  2308. },
  2309. replaceTable(obj, idx) {
  2310. obj.forEach(async (item, index) => {
  2311. let i = idx == -1 ? index : idx;
  2312. let row = JSON.parse(JSON.stringify(this.defaultForm));
  2313. row.key = this.form.datasource.length + 1;
  2314. let parasm = idx == -1 ? row : this.form.datasource[i];
  2315. this.$set(parasm, 'customerMark', this.customerMark);
  2316. this.$set(parasm, 'productId', item.productId);
  2317. this.$set(parasm, 'categoryName', item.productName);
  2318. this.$set(parasm, 'productCategoryId', item.categoryLevelId);
  2319. this.$set(parasm, 'productBrand', item.productBrand);
  2320. this.$set(parasm, 'productCategoryName', item.categoryLevelPath);
  2321. this.$set(parasm, 'productCode', item.productCode);
  2322. this.$set(parasm, 'productName', item.productName);
  2323. this.$set(parasm, 'modelType', item.categoryModel);
  2324. this.$set(parasm, 'availableCountBase', item.measureQuantity);
  2325. this.$set(parasm, 'measuringUnit', item.measuringUnit);
  2326. this.$set(parasm, 'specification', item.specification);
  2327. this.$set(parasm, 'weightUnit', item.weightUnit);
  2328. this.$set(parasm, 'singleWeight', item.weight);
  2329. this.$set(parasm, 'pricingWay', 1);
  2330. this.$set(parasm, 'arrivalWay', item.arrivalWay || 1);
  2331. this.$set(parasm, 'batchNo', item.batchNo);
  2332. this.$set(parasm, 'imgCode', '');
  2333. this.$set(parasm, 'produceType', item.componentAttribute);
  2334. let goodsData = await getGoodsByCategoryId(item.productId);
  2335. goodsData = goodsData.filter((item) => item.approvalStatus == 2);
  2336. if (goodsData?.length) {
  2337. let goodsPriceList = goodsData[0]?.goodsPriceList[0];
  2338. this.$set(parasm, 'goodsId', goodsData[0].id);
  2339. this.$set(parasm, 'goodsPriceId', goodsPriceList.id);
  2340. this.$set(parasm, 'goodsPriceType', goodsPriceList.priceType);
  2341. this.$set(parasm, 'singlePrice', goodsPriceList.unitPrice || 0);
  2342. this.$set(
  2343. parasm,
  2344. 'notaxSinglePrice',
  2345. goodsPriceList.excludeTaxPrice
  2346. );
  2347. this.$set(parasm, 'taxRate', goodsPriceList.taxRate);
  2348. this.$set(parasm, 'discountSinglePrice', goodsPriceList.unitPrice);
  2349. this.$set(parasm, 'totalCount', '');
  2350. } else {
  2351. this.$set(parasm, 'singlePrice', 0);
  2352. }
  2353. if (item.modelKey) {
  2354. this.$set(parasm, 'modelKey', item.modelKey.split(','));
  2355. }
  2356. if (item.colorKey) {
  2357. this.$set(parasm, 'colorKey', item.colorKey.split(','));
  2358. }
  2359. if (this.isSupplier) {
  2360. this.$set(
  2361. parasm,
  2362. 'entrustedEnterpriseIdList',
  2363. item.entrustedEnterpriseIdList
  2364. );
  2365. this.$set(
  2366. parasm,
  2367. 'entrustedEnterpriseId',
  2368. item.entrustedEnterpriseId
  2369. );
  2370. }
  2371. this.$set(parasm, 'approvalNumber', item.extField?.approvalNumber);
  2372. this.$set(
  2373. parasm,
  2374. 'packingSpecification',
  2375. item.extField.packingSpecification
  2376. );
  2377. this.$set(
  2378. parasm,
  2379. 'packageDispositionList',
  2380. item.packageDispositionList
  2381. );
  2382. if (item.packageDispositionList?.length) {
  2383. this.$set(
  2384. parasm,
  2385. this.countObj.unitIdKey,
  2386. item.packageDispositionList[0].id
  2387. );
  2388. this.$set(
  2389. parasm,
  2390. this.countObj.unitKey,
  2391. item.packageDispositionList[0].conversionUnit
  2392. );
  2393. }
  2394. this.$set(parasm, 'customerMark', this.customerMark);
  2395. if (item.purchaseOrigins?.length > 0) {
  2396. item.purchaseOrigins = item.purchaseOrigins.map((val) => val + '');
  2397. }
  2398. this.$set(parasm, 'provenance', item.purchaseOrigins || []);
  2399. // 初始化生产加工特有字段及未税小记
  2400. // 当quoteType为2时,数量默认设置为1
  2401. if (this.quoteType === 2) {
  2402. this.processSetValue(parasm);
  2403. }
  2404. if (idx == -1) {
  2405. this.form.datasource.push(row);
  2406. }
  2407. });
  2408. },
  2409. remove(index) {
  2410. this.form.datasource.splice(index, 1);
  2411. this.setSort();
  2412. this.changeAll();
  2413. },
  2414. // 重新排序
  2415. setSort() {
  2416. this.form.datasource.forEach((n, index) => {
  2417. n.key = index + 1;
  2418. });
  2419. },
  2420. // 添加临时产品
  2421. handlAdd() {
  2422. let item = JSON.parse(JSON.stringify(this.defaultForm));
  2423. item.key = this.form.datasource.length + 1;
  2424. item.customerMark = this.customerMark;
  2425. item.customerExpectDeliveryDeadline = dayjs(new Date()).format(
  2426. 'YYYY-MM-DD'
  2427. );
  2428. // 初始化生产加工特有字段及未税小记
  2429. // 当quoteType为2时,数量默认设置为1
  2430. if (this.quoteType === 2) {
  2431. this.processSetValue(item);
  2432. }
  2433. this.form.datasource.push(item);
  2434. },
  2435. processSetValue(parasm) {
  2436. this.$set(parasm, this.countObj.countKey, 1);
  2437. this.$set(parasm, 'thickNess', '');
  2438. this.$set(parasm, 'squareNumber', '');
  2439. this.$set(parasm, 'processingFeeBeforeTax', '');
  2440. this.$set(parasm, 'packagingFeeNotTaxed', '');
  2441. this.$set(parasm, 'transportationFeeWithoutTax', '');
  2442. this.$set(parasm, 'extraTax', 13);
  2443. this.$set(parasm, 'quotationSubtotalBeforeTax', '0.00');
  2444. this.$set(parasm, 'quotationSubtotalTax', '');
  2445. },
  2446. validateForm(callback) {
  2447. this.$refs.form.validate((valid, obj) => {
  2448. if (obj) {
  2449. let messages = Object.keys(obj).map((key) => obj[key][0]);
  2450. if (messages.length > 0) {
  2451. this.$message.warning(messages[0].message);
  2452. }
  2453. }
  2454. callback(valid);
  2455. });
  2456. },
  2457. goodsPriceTypeChange(row, index) {
  2458. if (row.goodsId) {
  2459. getGoodsPriceByCondition({
  2460. id: row.goodsId,
  2461. priceType: row.goodsPriceType
  2462. }).then((res) => {
  2463. if (res.id) {
  2464. this.$set(this.form.datasource[index], 'goodsPriceId', res.id);
  2465. this.$set(
  2466. this.form.datasource[index],
  2467. 'goodsPriceType',
  2468. res.priceType
  2469. );
  2470. this.$set(
  2471. this.form.datasource[index],
  2472. 'singlePrice',
  2473. res.unitPrice
  2474. );
  2475. this.$set(
  2476. this.form.datasource[index],
  2477. 'notaxSinglePrice',
  2478. res.excludeTaxPrice
  2479. );
  2480. this.$set(this.form.datasource[index], 'taxRate', res.taxRate);
  2481. this.$set(
  2482. this.form.datasource[index],
  2483. 'discountSinglePrice',
  2484. res.unitPrice
  2485. );
  2486. }
  2487. this.changeCount(row, index);
  2488. });
  2489. }
  2490. },
  2491. save() {
  2492. this.$emit('save');
  2493. }
  2494. }
  2495. };
  2496. </script>
  2497. <style lang="scss" scoped>
  2498. .headbox {
  2499. display: flex;
  2500. justify-content: space-between;
  2501. align-items: center;
  2502. .amount {
  2503. font-size: 14px;
  2504. font-weight: bold;
  2505. padding-right: 30px;
  2506. }
  2507. }
  2508. .time-form .el-form-item {
  2509. margin-bottom: 0 !important;
  2510. }
  2511. ::v-deep .period {
  2512. display: flex;
  2513. .borderleftnone {
  2514. .el-input--medium .el-input__inner {
  2515. border-top-right-radius: 0;
  2516. border-bottom-right-radius: 0;
  2517. }
  2518. }
  2519. .borderrightnone {
  2520. .el-input--medium .el-input__inner {
  2521. border-top-left-radius: 0;
  2522. border-bottom-left-radius: 0;
  2523. }
  2524. }
  2525. }
  2526. ::v-deep .time-form tbody > tr:hover > td {
  2527. background-color: transparent !important;
  2528. }
  2529. ::v-deep .time-form .el-table tr {
  2530. background-color: #ffffff;
  2531. }
  2532. .pricebox {
  2533. display: flex;
  2534. justify-content: flex-start;
  2535. align-items: center;
  2536. font-weight: bold;
  2537. }
  2538. :deep(.el-input-group__append) {
  2539. padding: 0;
  2540. }
  2541. </style>