orderDetailPart.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. <template>
  2. <div class="order-detail-part">
  3. <div
  4. v-if="isLoading == 1"
  5. v-loading="true"
  6. class="com-loading"></div>
  7. <template v-else-if="isLoading == 2">
  8. <!-- <div class="eco-tip" v-if="orderDetail.Emission_Total_Kg && orderDetail.Emission_Total_Kg != '0'">
  9. <div class="eco-tip-title">
  10. <img
  11. src="@/assets/img/esg/leaf.png"
  12. alt="eco"
  13. class="eco-tip-icon" />
  14. <span> Protecting Nature Starts with Your Choice</span>
  15. </div>
  16. <div class="eco-tip-desc">
  17. Your Eco-Friendly Purchase Generated
  18. <span class="eco-tip-co2"
  19. >{{ orderDetail.Emission_Total_Kg || 0 }} KG</span
  20. >
  21. Of Carbon Emissions. Together, We<br />
  22. Embrace Enyironmental Responsibility For A More Sustainable Future.
  23. </div>
  24. </div> -->
  25. <section class="main-header">
  26. <div class="main-header-mid flex between">
  27. <h1>Job Name:{{ orderDetail.Sales_Order_Title_Job_Name }}</h1>
  28. <img
  29. :src="orderDetail.user_logo"
  30. class="user_logo"
  31. v-if="orderDetail.user_logo" />
  32. </div>
  33. <div class="main-header-mid">
  34. <ul class="left">
  35. <li
  36. class="left-i link-div"
  37. v-if="isShow">
  38. <div @click="shareDialogVisible = true">
  39. <i class="el-icon-share"></i>
  40. <span>Client Tracking Share</span>
  41. </div>
  42. <!-- <div v-for="(item) in orderDetail.crm_esg_res?.flat()"
  43. @click="downloadEsg(item)"
  44. :key="item.id">
  45. <img src="@/assets/img/order/cer.png" />
  46. <span> DownLoad {{ item.name }}</span>
  47. </div> -->
  48. </li>
  49. <li
  50. class="left-i"
  51. v-if="orderDetail.crm_pr_res?.length">
  52. <image-list :data="orderDetail.crm_pr_res" />
  53. </li>
  54. </ul>
  55. <ul class="right">
  56. <li v-if="orderDetail.Job_Group && isShow">Order Type: {{ orderDetail.Job_Group }}</li>
  57. <li>Order No: {{ orderDetail.Reference }}</li>
  58. <li>Order Date: {{ formatStepDesc(orderDetail.Sales_Order_Created) }}</li>
  59. <li v-if="isShow">Payment Status: {{ orderDetail.Payment_Status1 }}</li>
  60. </ul>
  61. </div>
  62. <div class="steps margin-b-30">
  63. <p class="steps-title margin-b-50">Bulk Production</p>
  64. <el-steps
  65. :active="comOrderState"
  66. align-center
  67. :direction="computedStepDirection"
  68. finish-status="success"
  69. process-status="wait">
  70. <el-step
  71. title="Confirmed"
  72. :description="formatStepDesc(orderDetail.Order_Confirm)">
  73. </el-step>
  74. <el-step
  75. title="In Production"
  76. :description="
  77. formatStepDesc(orderDetail.Sampling_Factory_Confirm)
  78. "></el-step>
  79. <el-step
  80. title="QC Inspection"
  81. :description="formatStepDesc(orderDetail.GZ_WH)"></el-step>
  82. <el-step
  83. title="International Shipment"
  84. :description="
  85. formatStepDesc(orderDetail.International_transshipment)
  86. "></el-step>
  87. <el-step
  88. title="UK Warehouse"
  89. :description="formatStepDesc(orderDetail.AU_WH)"></el-step>
  90. <el-step
  91. :title="
  92. orderDetail.Order_Stage === 'Bulk Production Shipping'
  93. ? 'Domestic Delivery'
  94. : 'Shipped'
  95. "
  96. :description="formatStepDesc(orderDetail.AU_WH_Client)"></el-step>
  97. <el-step
  98. title="Delivered"
  99. :description="formatStepDesc(orderDetail.Delivered)"></el-step>
  100. </el-steps>
  101. </div>
  102. <div
  103. class="steps"
  104. :class="{ 'margin-b-30': stepShow }"
  105. v-if="orderDetail.Sample_Stage">
  106. <p
  107. class="steps-title pointer"
  108. :class="{ 'margin-b-50': stepShow }"
  109. @click="toggleStep">
  110. Sample Dispatch
  111. <i
  112. :class="
  113. stepShow ? 'el-icon-arrow-down' : 'el-icon-arrow-right'
  114. "></i>
  115. </p>
  116. <el-steps
  117. :active="comSampleState"
  118. align-center
  119. :space="180"
  120. v-if="stepShow"
  121. :direction="computedStepDirection"
  122. finish-status="success"
  123. process-status="wait">
  124. <el-step
  125. title="Factory Process"
  126. :description="
  127. formatStepDesc(orderDetail.Sample_Factory_Confirmed)
  128. ">
  129. </el-step>
  130. <el-step
  131. title="Sample Dispatching"
  132. :description="
  133. formatStepDesc(orderDetail.Sample_Dispatching)
  134. "></el-step>
  135. <el-step
  136. title="Sample Delivered"
  137. :description="
  138. formatStepDesc(orderDetail.Sample_Delivered)
  139. "></el-step>
  140. </el-steps>
  141. </div>
  142. </section>
  143. <section class="main-custom">
  144. <p class="sharing-title">Customer information</p>
  145. <div>
  146. <p class="sharing-subtitle">
  147. {{ isShow ? 'Billing' : 'Supplier' }} Address
  148. </p>
  149. <div class="sharing-address">
  150. <p>{{ orderDetail.Account_Name_name }}</p>
  151. <p>{{ orderDetail.Billing_Unit_Building_Name }}</p>
  152. <p>{{ orderDetail.Billing_Street }}</p>
  153. <p>{{ orderDetail.Billing_City }}</p>
  154. <p>{{ orderDetail.Billing_State }}</p>
  155. <p>{{ orderDetail.Billing_Code }}</p>
  156. <p>{{ orderDetail.Billing_Country }}</p>
  157. </div>
  158. </div>
  159. <div>
  160. <p class="sharing-subtitle">Shipping Address</p>
  161. <div class="sharing-address">
  162. <p>{{ orderDetail.Shipping_Unit_Building_Name }}</p>
  163. <p>{{ orderDetail.Shipping_Street }}</p>
  164. <p>{{ orderDetail.Shipping_City }}</p>
  165. <p>{{ orderDetail.Shipping_State }}</p>
  166. <p>{{ orderDetail.Shipping_Code }}</p>
  167. <p>{{ orderDetail.Shipping_Country }}</p>
  168. </div>
  169. </div>
  170. </section>
  171. <section>
  172. <p class="sharing-title">Shipping information</p>
  173. <el-table
  174. :data="orderDetail.shipping_tracking"
  175. style="width: 100%"
  176. :header-cell-style="{
  177. background: '#F7F8FC',
  178. color: '#101010',
  179. fontWeight: 'normal',
  180. }">
  181. <el-table-column
  182. type="expand"
  183. style="padding: 0">
  184. <template slot-scope="props">
  185. <el-table
  186. :data="props.row.test_pkg_details"
  187. style="margin-left: 50px; width: calc(100% - 50px)"
  188. :header-cell-style="{
  189. background: '#F7F8FC',
  190. color: '#101010',
  191. fontWeight: 'normal',
  192. }">
  193. <el-table-column
  194. prop="Product_name"
  195. label="Item & Description"></el-table-column>
  196. <el-table-column
  197. prop="Quantity_to_pack"
  198. label="QTY"
  199. width="450"></el-table-column>
  200. </el-table>
  201. </template>
  202. </el-table-column>
  203. <el-table-column
  204. prop="Title"
  205. label="Job Name"
  206. width="190"></el-table-column>
  207. <el-table-column
  208. prop="Courier"
  209. label="Carrier"
  210. width="190"></el-table-column>
  211. <el-table-column
  212. prop="Tracking_No"
  213. label="Tracking#"
  214. width="190"></el-table-column>
  215. <el-table-column
  216. prop="Package_Status"
  217. label="Shipment Status"
  218. width="190"></el-table-column>
  219. <el-table-column
  220. label="Delivery Address"
  221. width="250">
  222. <template slot-scope="scope">
  223. <span>
  224. {{ scope.row.Shipping_Unit_Building_Name }}<br />
  225. {{ scope.row.Shipping_Street }}<br />
  226. {{ scope.row.Shipping_City }}<br />
  227. {{ scope.row.Shipping_State }}
  228. </span>
  229. </template>
  230. </el-table-column>
  231. <el-table-column
  232. prop="Tracking_URL"
  233. label=""
  234. width="200">
  235. <template
  236. slot-scope="scope"
  237. v-if="scope.row.Tracking_URL">
  238. <el-button
  239. size="mini"
  240. @click.native="openTracking_URL(scope.row.Tracking_URL)"
  241. style="background-color: rgb(0, 33, 59); color: #fff"
  242. plain
  243. >TRACK SHIPMENT</el-button
  244. ></template
  245. >
  246. </el-table-column>
  247. </el-table>
  248. </section>
  249. <section class="orderTable">
  250. <p class="sharing-title">Products Information</p>
  251. <el-table
  252. :data="orderDetail.sales_orders_details"
  253. style="width: 100%"
  254. :header-cell-style="{
  255. background: '#fff',
  256. color: '#101010',
  257. fontWeight: 'normal',
  258. }">
  259. <el-table-column
  260. type="index"
  261. label="S.NO"
  262. width="70"
  263. fixed>
  264. </el-table-column>
  265. <el-table-column
  266. label="Product Name"
  267. min-width="300">
  268. <template slot-scope="scope">
  269. <p class="colorBlue">{{ scope.row.product_name }}</p>
  270. <!-- <p class="table-list-co2" v-if="scope.row.Emision_Details_value && scope.row.Emision_Details_value != '0'">
  271. <img src="@/assets/img/esg/co2_green.png" alt="CO2" class="co2-icon" />
  272. <span>{{ scope.row.Emision_Details_value }} kg CO₂e</span>
  273. </p> -->
  274. <p v-html="scope.row.product_description"></p>
  275. <!-- <p :class="scope.row.showMore?'ellipsis':''" v-html="scope.row.product_description"></p>
  276. <p class="colorBlue cursor" @click="toggleShow(scope.row)" v-if="scope.row.product_description">{{scope.row.showMore?'Show More':'Conceal'}}<i :class="scope.row.showMore?'el-icon-caret-bottom':'el-icon-caret-top'"></i></p> -->
  277. </template>
  278. </el-table-column>
  279. <el-table-column
  280. prop="quantity"
  281. label="Quantity"
  282. align="left"
  283. :width="isShow ? 125 : 200">
  284. </el-table-column>
  285. <template v-if="isShow">
  286. <el-table-column
  287. prop="list_price"
  288. :label="`List Price(${comCurrency})`"
  289. width="125">
  290. <template slot-scope="scope">
  291. {{ transformNumber(scope.row.list_price) }}
  292. </template>
  293. </el-table-column>
  294. <el-table-column
  295. prop="amount"
  296. :label="`Amount(${comCurrency})`"
  297. width="125">
  298. <template slot-scope="scope">
  299. {{ transformNumber(scope.row.amount) }}
  300. </template>
  301. </el-table-column>
  302. <el-table-column
  303. prop="Tax"
  304. :label="`Tax(${comCurrency})`"
  305. width="125">
  306. <template slot-scope="scope">
  307. {{ transformNumber(scope.row.Tax) }}
  308. </template>
  309. </el-table-column>
  310. <el-table-column
  311. prop="Discount"
  312. :label="`Discount(${comCurrency})`"
  313. width="125">
  314. <template slot-scope="scope">
  315. {{ transformNumber(scope.row.Discount) }}
  316. </template>
  317. </el-table-column>
  318. <el-table-column
  319. prop="net_total"
  320. :label="`Total(${comCurrency})`"
  321. width="125">
  322. <template slot-scope="scope">
  323. {{ transformNumber(scope.row.net_total) }}
  324. </template>
  325. </el-table-column>
  326. </template>
  327. </el-table>
  328. <div
  329. class="table-wrap"
  330. v-if="isShow">
  331. <table class="total">
  332. <tr>
  333. <td>Sub Total</td>
  334. <td>
  335. {{ comCurrency }} {{ transformNumber(orderDetail.Sub_Total) }}
  336. </td>
  337. </tr>
  338. <tr>
  339. <td>Total Taxes</td>
  340. <td>
  341. {{ comCurrency }} {{ transformNumber(orderDetail.Tax_Total) }}
  342. </td>
  343. </tr>
  344. <tr>
  345. <td>Total Discount</td>
  346. <td>
  347. {{ comCurrency }}
  348. {{ transformNumber(orderDetail.Total_Including_Discount) }}
  349. </td>
  350. </tr>
  351. <tr>
  352. <td>Adjustment</td>
  353. <td>
  354. {{ comCurrency }}
  355. {{ transformNumber(orderDetail.Total_Adjustment) }}
  356. </td>
  357. </tr>
  358. <tr>
  359. <td>Grand Total</td>
  360. <td>
  361. {{ comCurrency }} {{ transformNumber(orderDetail.Grand_Total) }}
  362. </td>
  363. </tr>
  364. </table>
  365. </div>
  366. </section>
  367. <!-- <section
  368. v-if="orderDetail.Order_Stage === 'Sales Order Created'" style="text-align: right;border: none;">
  369. <el-button
  370. v-if="orderDetail.Order_Stage === 'Sales Order Created'"
  371. @click="openApproved(orderDetail)"
  372. size="small"
  373. style="background-color: rgb(0, 33, 59); color: #fff;"
  374. plain
  375. >Approved</el-button>
  376. </section> -->
  377. </template>
  378. <div v-else>
  379. <el-empty description="No Data"></el-empty>
  380. </div>
  381. <el-dialog
  382. :lock-scroll="false"
  383. :visible.sync="urlDialogShow"
  384. center
  385. width="850px"
  386. top="20vh">
  387. <iframe
  388. :src="Tracking_URL"
  389. style="width: 100%; height: 500px"
  390. frameborder="0"></iframe>
  391. </el-dialog>
  392. <export-dialog
  393. :emailForm="shareForm"
  394. :visible.sync="shareDialogVisible"
  395. :title="'Client Tracking Share (no pricing displayed)'"
  396. :labelShow="false"></export-dialog>
  397. </div>
  398. </template>
  399. <script>
  400. import throttle from 'lodash.throttle'
  401. import { mapMutations } from 'vuex'
  402. import { round } from '@/utils/price.js'
  403. export default {
  404. name: 'OrderDetailPart',
  405. props: {
  406. isShow: {
  407. // 订单分享页面隐藏元素
  408. type: Boolean,
  409. default: true,
  410. },
  411. hasUid: {
  412. type: Boolean,
  413. default: true,
  414. },
  415. },
  416. data() {
  417. return {
  418. orderDetail: {},
  419. isLoading: 1,
  420. packageTable: [],
  421. stepShow: false,
  422. urlDialogShow: false,
  423. shareDialogVisible: false,
  424. loginCount: 0,
  425. shareForm: {
  426. Link: '',
  427. },
  428. Tracking_URL: '',
  429. stepConfig: {
  430. 'Order Confirmed': 1,
  431. 'Factory Confirmed': 2,
  432. 'GZ WH': 3,
  433. Transshipment: 4,
  434. 'AU WH': 5,
  435. 'AUWH - Client': 6,
  436. 'Bulk Production Shipping': 6,
  437. 'Bulk Production Delivered': 7,
  438. 'Completed Sales Order': 7,
  439. 'Factory Process': 1,
  440. 'Sample Dispatching': 2,
  441. 'Sample Delivered': 3,
  442. },
  443. computedStepDirection: 'horizontal',
  444. }
  445. },
  446. computed: {
  447. loginSuccess() {
  448. return this.$store.state.loginSuccess
  449. },
  450. comCurrency() {
  451. return this.orderDetail.Currency
  452. },
  453. comOrderState() {
  454. if (this.orderDetail.Order_Stage === 'Cancelled') {
  455. return 0
  456. }
  457. return this.stepConfig[this.orderDetail.Order_Stage]
  458. },
  459. comSampleState() {
  460. return this.stepConfig[this.orderDetail.Sample_Stage]
  461. },
  462. },
  463. watch: {
  464. loginSuccess(newVal) {
  465. if (newVal) {
  466. this.getOrderDetail() // 当登录成功后调用获取订单详情
  467. this.$store.commit('setLoginSuccess', false)
  468. }
  469. },
  470. },
  471. beforeMount() {
  472. window.addEventListener('resize', this.judgeStepDirection, false)
  473. this.judgeStepDirection()
  474. },
  475. created() {
  476. this.getOrderDetail()
  477. },
  478. beforeDestroy() {
  479. window.removeEventListener('resize', this.judgeStepDirection, false)
  480. },
  481. methods: {
  482. ...mapMutations({ openDialog: 'openDialog' }),
  483. judgeStepDirection: throttle(function () {
  484. this.computedStepDirection =
  485. window.document.body.clientWidth >= 1000 ? 'horizontal' : 'vertical'
  486. }, 300),
  487. toggleStep() {
  488. this.stepShow = !this.stepShow
  489. },
  490. getOrderDetail() {
  491. let path = ''
  492. let data = {}
  493. if (this.isShow) {
  494. const { id } = this.$store.state.userInfo
  495. const { crm, id: queryId } = this.$route.query
  496. path = '/uk-api/crmdata/orders_detail'
  497. this.shareForm.Link = `https://www.trackship.com.au/orderShare/${id}/${crm}/${queryId}`
  498. data = { accounts_id: crm, id: queryId }
  499. } else {
  500. path = '/uk-api/crmdata/showOrdersDetail'
  501. if (this.hasUid) {
  502. const { uid, aid, id } = this.$route.params
  503. data = { user_id: uid, accounts_id: aid, id }
  504. } else {
  505. const { aid, id } = this.$route.params
  506. data = { accounts_id: aid, id }
  507. }
  508. }
  509. this.$axios
  510. .post(path, data)
  511. .then(res => {
  512. if (res.result === null) {
  513. this.handleBranchLogic()
  514. }
  515. this.orderDetail = res.result
  516. if (this.orderDetail.shipping_tracking?.length) {
  517. const isDelivered = true
  518. for (const items of this.orderDetail.shipping_tracking) {
  519. if (items.test_pkg_details?.length) {
  520. items.test_pkg_details.forEach(item => {
  521. item.Courier = items.Courier
  522. item.Tracking_No = items.Tracking_No
  523. item.Package_Status = items.Package_Status
  524. item.Tracking_URL = items.Tracking_URL
  525. })
  526. }
  527. }
  528. }
  529. if (this.orderDetail.sales_orders_details?.length) {
  530. if (this.isShow) {
  531. this.orderDetail.sales_orders_details.forEach(items => {
  532. this.$set(items, 'showMore', true)
  533. })
  534. } else {
  535. this.orderDetail.sales_orders_details =
  536. this.orderDetail.sales_orders_details
  537. .filter(item => {
  538. return (
  539. item.product_Product_Code !== 'PC Setup Service' &&
  540. item.product_Product_Code !== 'PC Freight'
  541. )
  542. })
  543. .map(item => {
  544. this.$set(item, 'showMore', true)
  545. return item
  546. })
  547. }
  548. }
  549. this.isLoading = 2
  550. })
  551. .catch(() => {
  552. this.handleBranchLogic()
  553. })
  554. },
  555. handleBranchLogic() {
  556. this.isLoading = 3
  557. if (this.loginCount) {
  558. this.$router.push('/')
  559. return
  560. }
  561. this.isShow &&
  562. setTimeout(() => {
  563. this.openDialog()
  564. this.loginCount = 1
  565. }, 1000)
  566. },
  567. transformNumber(value) {
  568. return round(Number(value)).toFixed(2)
  569. },
  570. formatStepDesc(date, isUnix = false) {
  571. return this.$utils.formatTime(date, 'DD/MM/YYYY', isUnix)
  572. },
  573. toggleShow(row) {
  574. row.showMore = !row.showMore
  575. },
  576. openTracking_URL(url) {
  577. this.Tracking_URL = url
  578. this.urlDialogShow = true
  579. },
  580. download(url) {
  581. var urlStr = url.match('[^/]+(?!.*/)')[0]
  582. this.$utils.downloadBlob(url, urlStr)
  583. },
  584. downloadEsg(item) {
  585. if (!item.id) {
  586. this.$message.error('No report available for download')
  587. return
  588. }
  589. this.$axios
  590. .post('Crmdata/downloadreport', { id: item.id, name: item.name })
  591. .then(res => {
  592. if (res.result) {
  593. this.$utils.downloadBlob(
  594. res.result?.data,
  595. decodeURIComponent(res.result?.url_name)
  596. )
  597. } else {
  598. this.$message.error('Download failed, please try again later')
  599. }
  600. })
  601. .catch(() => {
  602. this.$message.error('Download failed, please try again later')
  603. })
  604. },
  605. openApproved(row) {
  606. this.$confirm(
  607. `
  608. <div style="text-align:center;">
  609. <h3 style="margin:0 0 10px;color:#333;">Ready to order?</h3>
  610. <p style="margin:0;font-size:16px;color:#333;">Your total is <b>${this.transformNumber(
  611. row.Grand_Total
  612. )}</b>. Confirm to place your order.</p>
  613. </div>
  614. `,
  615. '',
  616. {
  617. dangerouslyUseHTMLString: true,
  618. confirmButtonText: 'Confirm',
  619. cancelButtonText: 'Cancel',
  620. confirmButtonClass: 'el-button',
  621. cancelButtonClass: 'el-button--info',
  622. center: true,
  623. showClose: false,
  624. confirmButtonClass: 'com-btnblack',
  625. }
  626. ).then(() => {
  627. this.$router.push({
  628. path: '/so-confirm',
  629. query: { id: row.sales_orders_id, pc_psw: row.HASH },
  630. })
  631. })
  632. },
  633. },
  634. }
  635. </script>
  636. <style lang="scss" scoped>
  637. @import '../detail.scss';
  638. </style>