[javascript] SalesOrdersDetail.vue

Viewer

copyrawdownloadembedprintName: SalesOrdersDetail.vue
  1. <template>
  2.   <v-container grid-list-lg fluid pa-0>
  3.     <v-dialog v-if="fullscreenLoading" v-model="fullscreenLoading" fullscreen full-width>
  4.       <v-container fluid fill-height style="background-color: rgba(255, 255, 255, 0.5);">
  5.         <v-layout justify-center align-center>
  6.           <v-progress-circular
  7.             indeterminate
  8.             color="primary">
  9.           </v-progress-circular>
  10.         </v-layout>
  11.       </v-container>
  12.     </v-dialog>
  13.     <v-snackbar
  14.       v-model="snackbar.value"
  15.       :color="snackbar.color"
  16.       top
  17.       multi-line
  18.       block
  19.     >
  20.       {{ snackbar.message }}
  21.       <v-btn flat color="dark" @click.native="snackbar.value = false"><v-icon color="white">cancel</v-icon></v-btn>
  22.     </v-snackbar>
  23.     <v-layout column>
  24.       <v-flex>
  25.         <v-layout row align-center>
  26.           <v-flex shrink>
  27.             <h1 class="title font-weight-bold" id="invoice-sales-order-detail">{{ renderSODataID }}</h1>
  28.           </v-flex>
  29.           <v-flex shrink>
  30.             <v-chip :class="[salesOrderData.status, 'white--text']">{{ salesOrderData.status ? _(salesOrderData.status.replace(/_/g, ' ')).capitalize() : '' }}</v-chip>
  31.           </v-flex>
  32.         </v-layout>
  33.       </v-flex>
  34.       <v-flex>
  35.         <v-card>
  36.           <v-card-text>
  37.             <v-container grid-list-xl fluid pa-0>
  38.               <v-layout row wrap>
  39.                 <v-flex xs12 sm6>
  40.                   <v-layout row justify-space-between>
  41.                     <v-flex xs6>
  42.                       <span class="body-1 light-grey">Merchant Name</span>
  43.                     </v-flex>
  44.                     <v-flex xs6 class="text-xs-right">
  45.                       <span class="body-1">{{ renderMerchantName(salesOrderData) || '-' }}</span>
  46.                     </v-flex>
  47.                   </v-layout>
  48.                 </v-flex>
  49.                 <v-flex xs12 sm6>
  50.                   <v-layout row justify-space-between>
  51.                     <v-flex xs6>
  52.                       <span class="body-1 light-grey">Owner Name</span>
  53.                     </v-flex>
  54.                     <v-flex xs6 class="text-xs-right">
  55.                       <span class="body-1">{{ renderOwnerName(salesOrderData) || '-' }}</span>
  56.                     </v-flex>
  57.                   </v-layout>
  58.                 </v-flex>
  59.                 <v-flex xs12 sm6>
  60.                   <v-layout row justify-space-between>
  61.                     <v-flex xs6>
  62.                       <span class="body-1 light-grey">City</span>
  63.                     </v-flex>
  64.                     <v-flex xs6 class="text-xs-right">
  65.                       <span class="body-1">{{ renderMerchantcity(salesOrderData) || '-' }}</span>
  66.                     </v-flex>
  67.                   </v-layout>
  68.                 </v-flex>
  69.                 <v-flex xs12 sm6>
  70.                   <v-layout row justify-space-between>
  71.                     <v-flex xs6>
  72.                       <span class="body-1 light-grey">Owner Phone Number</span>
  73.                     </v-flex>
  74.                     <v-flex xs6 class="text-xs-right">
  75.                       <span class="body-1">{{ renderOwnerPhoneNumber(salesOrderData) || '-' }}</span>
  76.                     </v-flex>
  77.                   </v-layout>
  78.                 </v-flex>
  79.                 <v-flex xs12 sm6>
  80.                   <v-layout row justify-space-between>
  81.                     <v-flex xs6>
  82.                       <span class="body-1 light-grey">Address</span>
  83.                     </v-flex>
  84.                     <v-flex xs6 class="text-xs-right">
  85.                       <span class="body-1">{{ renderMerchantAddress(salesOrderData) || '-' }}</span>
  86.                     </v-flex>
  87.                   </v-layout>
  88.                 </v-flex>
  89.                 <v-flex xs12 sm6>
  90.                   <v-layout row justify-space-between>
  91.                     <v-flex xs6>
  92.                       <span class="body-1 light-grey">Sales Name</span>
  93.                     </v-flex>
  94.                     <v-flex xs6 class="text-xs-right">
  95.                       <span class="body-1">{{ renderSalesName(salesOrderData) || '-' }}</span>
  96.                     </v-flex>
  97.                   </v-layout>
  98.                 </v-flex>
  99.                 <v-flex xs12 sm6>
  100.                   <v-layout row justify-space-between>
  101.                     <v-flex xs6>
  102.                       <span class="body-1 light-grey">Post Code</span>
  103.                     </v-flex>
  104.                     <v-flex xs6 class="text-xs-right">
  105.                       <span class="body-1">{{ renderMerchantPostcode(salesOrderData) || '-' }}</span>
  106.                     </v-flex>
  107.                   </v-layout>
  108.                 </v-flex>
  109.                 <v-flex xs12 sm6>
  110.                   <v-layout row justify-space-between>
  111.                     <v-flex xs6>
  112.                       <span class="body-1 light-grey">Sales Phone Number</span>
  113.                     </v-flex>
  114.                     <v-flex xs6 class="text-xs-right">
  115.                       <span class="body-1">{{ renderSalesPhoneNumber(salesOrderData) || '-' }}</span>
  116.                     </v-flex>
  117.                   </v-layout>
  118.                 </v-flex>
  119.                 <v-flex xs12 sm6>
  120.                   <v-layout row justify-space-between>
  121.                     <v-flex xs6>
  122.                       <span class="body-1 light-grey">Patokan</span>
  123.                     </v-flex>
  124.                     <v-flex xs6 class="text-xs-right">
  125.                       <span class="body-1">{{ renderMerchantPatokan(salesOrderData) || '-' }}</span>
  126.                     </v-flex>
  127.                   </v-layout>
  128.                 </v-flex>
  129.                 <v-flex xs12 sm6>
  130.                   <v-layout row justify-space-between>
  131.                     <v-flex xs6>
  132.                       <span class="body-1 light-grey">Operation Hour</span>
  133.                     </v-flex>
  134.                     <v-flex xs6 class="text-xs-right">
  135.                       <span class="body-1">{{ renderOperationHour(salesOrderData) || '-' }}</span>
  136.                     </v-flex>
  137.                   </v-layout>
  138.                 </v-flex>
  139.               </v-layout>
  140.             </v-container>
  141.           </v-card-text>
  142.         </v-card>
  143.       </v-flex>
  144.       <v-flex>
  145.         <v-layout row wrap>
  146.           <v-flex xs12>
  147.             <v-card>
  148.               <v-card-text class="pa-0 py-3">
  149.                 <v-layout row wrap>
  150.                   <v-flex xs12 class="mx-3 mb-2">
  151.                     <v-tabs
  152.                       v-model="tab"
  153.                       slider-color="custom-green"
  154.                       light
  155.                       >
  156.                       <v-tab
  157.                         style="text-transform: capitalize;"
  158.                         v-for="opt in tabOpt"
  159.                         :key="opt.value"
  160.                         :disabled="opt.disabled"
  161.                         class="grey--text text--darken-3"
  162.                       >
  163.                         <span class="subheading font-weight-bold">{{ opt.text }}</span>
  164.                       </v-tab>
  165.                     </v-tabs>
  166.                   </v-flex>
  167.                   <v-flex xs12 class="mx-3 mb-2">
  168.                     <table id="table-detail-order-fulfill" width="100%" class="mx-auto" border="0" cellspacing="0">
  169.                       <tr class="table-row-underline">
  170.                         <td class="py-3 px-1"><b>SKU</b></td>
  171.                         <td class="py-3 px-1"><b>Product</b></td>
  172.                         <td class="py-3 px-1"><b>Unit</b></td>
  173.                         <td class="py-3 px-1"><b>{{ currentTab ? currentTab.text : '' }}</b></td>
  174.                         <td class="py-3 px-1"></td>
  175.                         <td class="py-3 px-1"></td>
  176.                         <td class="py-3 px-1"></td>
  177.                         <td class="py-3 px-1" align="right"><b>Subtotal</b></td>
  178.                       </tr>
  179.                       <template v-for="(product, index) in flattenProductUnitComposition(objectSelected)">
  180.                         <tr class="px-3 table-row-underline" :key="`${product.product_id}${unit.unit_name}${index}`">
  181.                           <td class="py-3 px-1">{{ product.product_id }}</td>
  182.                           <td class="py-3 px-1" width="170px">
  183.                             <span>{{ product.name || '-'}}</span>
  184.                           </td>
  185.                           <td class="py-3 px-1">
  186.                             <span>{{ product.units[0].unit_name ? _(product.units[0].unit_name).capitalize() : '-'}} </span><br>
  187.                           </td>
  188.                           <td class="py-3 px-1" width="90px" align="right">
  189.                             {{ (product.units[0].quantity ? product.units[0].quantity : '-') | thousandSeparator}}
  190.                           </td>
  191.                           <td class="py-3 px-1" width="190px"></td>
  192.                           <td class="py-3 px-1"></td>
  193.                           <td class="py-3 px-1"></td>
  194.                           <td class="py-3 px-1" align="right">
  195.                             {{ unit.subtotal_price | formatCurrency }}
  196.                           </td>
  197.                         </tr>
  198.                       </template>
  199.                       <tr v-if="isB2C === false && currentTab ? (currentTab.value !== 'return') : false" class="px-3 table-row-underline">
  200.                         <td class="py-3 px-1">
  201.                         </td>
  202.                         <td class="py-3 px-1">
  203.                         </td>
  204.                         <td class="py-3 px-1">
  205.                         </td>
  206.                         <td class="py-3 px-1">
  207.                         </td>
  208.                         <td class="py-3 px-1"></td>
  209.                         <td class="py-3 px-1"></td>
  210.                         <td class="py-3 px-5">
  211.                           Discount
  212.                         </td>
  213.                         <td class="py-3 px-1" align="right">
  214.                           - {{ currentDiscount | formatCurrency}}
  215.                         </td>
  216.                       </tr>
  217.                       <tr>
  218.                         <td class="py-3 px-1">
  219.                         </td>
  220.                         <td class="py-3 px-1">
  221.                         </td>
  222.                         <td class="py-3 px-1">
  223.                         </td>
  224.                         <td class="py-3 px-1">
  225.                         </td>
  226.                         <td class="py-3 px-1"></td>
  227.                         <td class="py-3 px-1"></td>
  228.                         <td class="py-3 px-5"><b>Total Price</b></td>
  229.                         <td class="py-3 px-1" align="right">
  230.                           <b>{{ getTotalPrice() | formatCurrency }}</b>
  231.                         </td>
  232.                       </tr>
  233.                     </table>
  234.                   </v-flex>
  235.                 </v-layout>
  236.                 
  237.               </v-card-text>
  238.             </v-card>
  239.           </v-flex>
  240.         </v-layout>
  241.       </v-flex>
  242.       <v-flex v-if="salesExchangeId !== ''">
  243.         <v-layout row wrap>
  244.           <v-flex xs12>
  245.             <v-card>
  246.               <v-card-title>
  247.                 <v-layout row wrap>
  248.                   <v-flex xs12><span class="subheading font-weight-bold">{{ salesExchangeData.id }}</span></v-flex>
  249.                 </v-layout>
  250.               </v-card-title>
  251.               <v-divider></v-divider>
  252.               <v-card-text>
  253.                 <table id="table-detail-order-fulfill" width="100%" class="mx-auto" border="0" cellspacing="0">
  254.                   <tr>
  255.                     <td><b>RECENT SALES ORDER</b></td>
  256.                     <td><b>PRODUCT NAME</b></td>
  257.                     <td><b>Unit</b></td>
  258.                     <td><b>{{ currentTab ? currentTab.text : '' }}</b></td>
  259.                   </tr>
  260.                   <template v-for="order in salesExchangeData.orders">
  261.                     <template v-for="product in order.products">
  262.                       <tr class="px-3" :key="`${product.product_id}`">
  263.                         <td>
  264.                           {{ salesExchangeData.sales_order_id || '-'}}
  265.                         </td>
  266.                         <td>
  267.                           {{ product.name ? _(product.name).capitalize() : '-'}}
  268.                         </td>
  269.                         <td>
  270.                           <div v-for="unit in product.units" :key="unit.unit_name">
  271.                             <td>{{ unit.unit_name }}</td>
  272.                           </div>
  273.                         </td>
  274.                         <td>
  275.                           <div v-for="unit in product.units" :key="unit.unit_name + 's'">
  276.                             <td>{{ renderQuantitySE(unit.quantity) }}</td>
  277.                           </div>
  278.                         </td>
  279.                       </tr>
  280.                     </template>
  281.                   </template>
  282.                       
  283.                 </table>
  284.               </v-card-text>
  285.             </v-card>
  286.           </v-flex>
  287.         </v-layout>
  288.       </v-flex>
  289.       <v-flex>
  290.         <v-layout row wrap>
  291.           <v-flex xs12>
  292.             <v-card>
  293.               <v-card-title>
  294.                 <v-layout row wrap>
  295.                   <v-flex xs12><span class="body-2">Notes</span></v-flex>
  296.                   <v-flex xs12><span class="body-1">{{ salesOrderData.notes || '-' }}</span></v-flex>
  297.                 </v-layout>
  298.               </v-card-title>
  299.             </v-card>
  300.           </v-flex>
  301.         </v-layout>
  302.       </v-flex>
  303.       <v-flex>
  304.         <v-layout row wrap>
  305.           <v-flex xs6>
  306.             <v-card>
  307.               <v-card-title>
  308.                 <v-layout row wrap>
  309.                   <v-flex xs12><span class="body-2">{{ salesOrderData.delivery_order_id || '-' }}</span></v-flex>
  310.                   <v-flex xs12>
  311.                     <v-layout row wrap>
  312.                       <v-flex xs4>
  313.                         <span class="body-1">DO Status</span>
  314.                       </v-flex>
  315.                       <v-flex xs4>: {{ renderDOStatus(salesOrderData) || '-' }}</v-flex>
  316.                       <v-flex xs4></v-flex>
  317.                       <v-flex xs4>
  318.                         <span class="body-1"></span>
  319.                       </v-flex>
  320.                       <v-flex xs4> </v-flex>
  321.                       <v-flex xs4></v-flex>
  322.                     </v-layout>
  323.                   </v-flex>
  324.                 </v-layout>
  325.               </v-card-title>
  326.             </v-card>
  327.           </v-flex>
  328.           <v-flex xs6>
  329.             <v-card>
  330.               <v-card-title>
  331.                 <v-layout row wrap>
  332.                   <v-flex xs12><span class="body-2">{{ salesOrderData.payment_details ? salesOrderData.payment_details.payment_type : ''  | orderPaymentText }}</span></v-flex>
  333.                   <v-flex xs12>
  334.                     <v-layout row wrap>
  335.                       <v-flex xs4>
  336.                         <span class="body-1">Payment Status</span>
  337.                       </v-flex>
  338.                       <v-flex xs4>: {{ renderPaymentStatus(salesOrderData) }}</v-flex>
  339.                       <v-flex xs4></v-flex>
  340.                       <v-flex xs4>
  341.                         <span class="body-1">Payment Date</span>
  342.                       </v-flex>
  343.                       <v-flex xs4>: {{ renderPaymentDate(salesOrderData) }}</v-flex>
  344.                       <v-flex xs4></v-flex>
  345.                     </v-layout>
  346.                   </v-flex>
  347.                   
  348.                 </v-layout>
  349.               </v-card-title>
  350.             </v-card>
  351.           </v-flex>
  352.         </v-layout>
  353.       </v-flex>
  354.       <v-flex>
  355.         <v-layout row wrap>
  356.           <v-flex xs6>
  357.             <v-card>
  358.               <v-card-title>
  359.                 <v-layout row wrap>
  360.                   <v-flex xs12><span class="body-2">{{ renderVoucher(salesOrderData) || '-' }}</span></v-flex>
  361.                   <v-flex xs12>
  362.                     <v-layout row wrap>
  363.                       <v-flex xs3>
  364.                         <span class="body-1">Type</span>
  365.                       </v-flex>
  366.                       <v-flex xs5>: {{ getVoucherType(salesOrderData) || '-' }}</v-flex>
  367.                       <v-flex xs4></v-flex>
  368.                       <v-flex xs3>
  369.                         <span class="body-1">Code</span>
  370.                       </v-flex>
  371.                       <v-flex xs5>: {{ renderCode(salesOrderData) || '-' }}</v-flex>
  372.                       <v-flex xs4></v-flex>
  373.                       <v-flex xs3>
  374.                         <span class="body-1">Value Rules</span>
  375.                       </v-flex>
  376.                       <v-flex xs5>: {{ getValueRulesText || '-' }}</v-flex>
  377.                       <v-flex xs4></v-flex>
  378.                     </v-layout>
  379.                   </v-flex>
  380.                 </v-layout>
  381.               </v-card-title>
  382.             </v-card>
  383.           </v-flex>
  384.           <v-flex xs6>
  385.             <v-card>
  386.               <v-card-title>
  387.                 <v-layout row wrap>
  388.                   <v-flex xs12><span class="body-2">Sales Order Detail</span></v-flex>
  389.                   <v-flex xs12>
  390.                     <v-layout row wrap>
  391.                       <v-flex xs3>
  392.                         <span class="body-1">Order Date</span>
  393.                       </v-flex>
  394.                       <v-flex xs5>: {{ renderOrderDate(salesOrderData) || '-' }}</v-flex>
  395.                       <v-flex xs4></v-flex>
  396.                       <v-flex xs3>
  397.                         <span class="body-1">Delivery Date</span>
  398.                       </v-flex>
  399.                       <v-flex xs5>: {{ renderDeliveryDate(salesOrderData) || '-' }}</v-flex>
  400.                       <v-flex xs4></v-flex>
  401.                       <v-flex xs3>
  402.                         <span class="body-1">Paid Date</span>
  403.                       </v-flex>
  404.                       <v-flex xs5>: {{ renderPaidDate(salesOrderData) || '-' }}</v-flex>
  405.                       <v-flex xs4></v-flex>
  406.                       <v-flex xs3>
  407.                         <span class="body-1">Admin Notes</span>
  408.                       </v-flex>
  409.                       <v-flex xs5>: {{ renderAdminNotes(salesOrderData) || '-' }}</v-flex>
  410.                       <v-flex xs4></v-flex>
  411.                       <!-- <v-flex xs4>
  412.                         <span class="body-1">Admin Notes</span>
  413.                       </v-flex>
  414.                       <v-flex xs4>: Value</v-flex>
  415.                       <v-flex xs4></v-flex> -->
  416.                     </v-layout>
  417.                   </v-flex>
  418.                 </v-layout>
  419.               </v-card-title>
  420.             </v-card>
  421.           </v-flex>
  422.         </v-layout>
  423.       </v-flex>
  424.     </v-layout>
  425.   </v-container>
  426. </template>
  427.  
  428. <script>
  429. import _ from 'underscore'
  430. import moment from 'moment'
  431. import FormatCurrency from '../../filters/currency'
  432. export default {
  433.   data () {
  434.     return {
  435.       tab: null,
  436.       fullscreenLoading: false,
  437.       salesOrderData: {},
  438.       voucher: {},
  439.       salesExchangeData: {},
  440.       salesExchangeId: '',
  441.       filterOpt: [
  442.         {
  443.           text: 'REQUESTED',
  444.           value: 'requested'
  445.         },
  446.         {
  447.           text: 'FULFILLED',
  448.           value: 'fulfilled'
  449.         },
  450.         {
  451.           text: 'DELIVERED',
  452.           value: 'delivered'
  453.         },
  454.         {
  455.           text: 'RETURN',
  456.           value: 'return'
  457.         }
  458.       ],
  459.       headersSalesExchange: [
  460.         {
  461.           text: 'RECENT SALES ORDER',
  462.           value: 'name'
  463.         },
  464.         { text: 'PRODUCT NAME', value: 'calories' },
  465.         { text: 'UNIT', value: 'fat' },
  466.         { text: 'REQUESTED', value: 'carbs' },
  467.         { text: 'FULFILLED', value: 'protein' },
  468.         { text: 'DELIVERED', value: 'iron' },
  469.         { text: 'RETURN', value: 'iron' }
  470.       ],
  471.       snackbar: {
  472.         value: false,
  473.         color: 'primary',
  474.         message: ''
  475.       }
  476.     }
  477.   },
  478.   created () {
  479.     this.fetchSalesOrders()
  480.   },
  481.   computed: {
  482.     renderSODataID () {
  483.       return this.salesOrderData.id
  484.     },
  485.     tabOpt () {
  486.       let opt = []
  487.       this.filterOpt.forEach(=> {
  488.         let index = _.indexOf(this.flag, o.value)
  489.         if (index > -1) {
  490.           let newOpt = JSON.parse(JSON.stringify(o))
  491.           if (_.has(this.salesOrderData, 'products_' + newOpt.value + '_array') && !_.isEmpty(this.salesOrderData['products_' + newOpt.value + '_array'])) {
  492.             opt.push(newOpt)
  493.           }
  494.         }
  495.       })
  496.       return opt
  497.     },
  498.     getValueRulesText () {
  499.       let returnValue = '-'
  500.       if (!this.voucher) {
  501.         return returnValue
  502.       }
  503.       const voucherBenefit = this.voucher.benefit
  504.       const voucherRule = this.voucher.rules
  505.       if (!voucherBenefit || !voucherBenefit.discount || !voucherRule || !voucherRule.order) {
  506.         return returnValue
  507.       }
  508.       const discountObject = voucherBenefit.discount
  509.       returnValue = ''
  510.       if (discountObject.type === 'percentage' && discountObject.scope === 'cart') {
  511.         returnValue += `Discount cart ` + discountObject.value + `% Off Maximum ` + FormatCurrency(discountObject.maximum_amount)
  512.       } else if (discountObject.type === 'percentage' && discountObject.scope === 'product') {
  513.         returnValue += `Discount product ` + discountObject.products[0].value + `% Off Maximum ` + FormatCurrency(discountObject.products[0].maximum_amount)
  514.       } else if (discountObject.type === 'value' && discountObject.scope === 'product') {
  515.         let tempProduct = discountObject.products.map(=> `${e.name} ${FormatCurrency(e.value)}`).join(', ')
  516.         returnValue += 'Discount ' + tempProduct
  517.       } else if (discountObject.type === 'value' && discountObject.scope === 'cart') {
  518.         returnValue += 'Discount Cart ' + FormatCurrency(discountObject.value)
  519.       } else if (discountObject.type === 'value' && discountObject.value > 0) {
  520.         returnValue += `Discount Value ${FormatCurrency(discountObject.value)}`
  521.       }
  522.       const rulesStr = []
  523.       const minimumAmount = voucherRule.order.minimum_amount
  524.       if (minimumAmount) {
  525.         rulesStr.push(`min order ` + FormatCurrency(minimumAmount))
  526.       } else {
  527.         rulesStr.push(`min order Rp 300.000`)
  528.       }
  529.       const orderProducts = voucherRule.order.products
  530.       const orderProductsCategory = voucherRule.order.products_category
  531.       const minimumQty = voucherRule.order.minimum_quantity
  532.       const minimumAmountWording = minimumQty ? 'with minimum quantity of ' + minimumQty : ''
  533.       if (orderProducts) {
  534.         if (orderProducts.included) {
  535.           rulesStr.push('include product(s)' + orderProducts.included.map(product => product.name).join(' , ') + minimumAmountWording)
  536.         } else if (orderProducts.excluded) {
  537.           rulesStr.push('exclude product(s) ' + orderProducts.excluded.map(product => product.name).join(' , '))
  538.         }
  539.       } else if (orderProductsCategory) {
  540.         const productCategory = orderProductsCategory.type
  541.         const productCategoryIncluded = orderProductsCategory.included
  542.         if (productCategory === 'department') {
  543.           rulesStr.push('include products in Department ' + productCategoryIncluded.map(product => product.name).join(' , '))
  544.         } else if (productCategory === 'category') {
  545.           rulesStr.push('include products in Category ' + productCategoryIncluded.map(product => product.name).join(' , ') +
  546.             ' Department ' + productCategoryIncluded.map(product => product.department_name))
  547.         } else if (productCategory === 'subcategory') {
  548.           rulesStr.push(
  549.             'include products in Subcategory ' + productCategoryIncluded.map(product => product.name).join(' , ') +
  550.             ' Category ' + productCategoryIncluded.map(product => product.category_name) +
  551.             ' Department ' + productCategoryIncluded.map(product => product.department_name)
  552.           )
  553.         } else if (productCategory === 'brand') {
  554.           rulesStr.push('include products in Brand ' +
  555.             productCategoryIncluded.map(product => product.name).join(' , '))
  556.         }
  557.       }
  558.       returnValue += ' with ' + rulesStr.join(' and ')
  559.       // console.log('voucherRule', voucherRule)
  560.       if (voucherRule.order.type === 'all') {
  561.         returnValue += ' All Products'
  562.       }
  563.       return returnValue
  564.     },
  565.     flag () {
  566.       const flag = {
  567.         waiting_for_confirmation: ['requested'],
  568.         waiting_for_payment: ['requested'],
  569.         requested: ['requested'],
  570.         pending: ['requested'],
  571.         processed: ['requested', 'fulfilled'],
  572.         on_delivery: ['requested', 'fulfilled'],
  573.         delivered: ['requested', 'fulfilled', 'delivered', 'return'],
  574.         paid: ['requested', 'fulfilled', 'delivered', 'return'],
  575.         canceled: ['requested'],
  576.         expired: ['requested']
  577.       }
  578.       return _.isEmpty(this.salesOrderData) ? [] : flag[this.salesOrderData.status]
  579.     },
  580.     currentTab () {
  581.       return this.tabOpt[this.tab]
  582.     },
  583.     objectSelected () {
  584.       console.log(this.currentTab)
  585.       if (this.currentTab && _.has(this.salesOrderData, 'products_' + this.currentTab.value + '_array')) {
  586.         let products = this.salesOrderData['products_' + this.currentTab.value + '_array']
  587.         Object.values(products).forEach(product => {
  588.           if (product.hasOwnProperty('composite_items')) {
  589.             // test
  590.             product.units = product.composite_items.map(unit => ({
  591.               unit_name: 'Composite',
  592.               product_name: product.name,
  593.               quantity: product.quantity
  594.             }))
  595.           } else if (!product.hasOwnProperty('composite_items')) {
  596.             if (this.currentTab.value === 'requested') {
  597.               product.units = product.units.map(unit => ({
  598.                 ...unit,
  599.                 product_name: product.name
  600.               }))
  601.             } else if (this.currentTab.value === 'fulfilled') {
  602.               product.units = product.fulfilled_units.map(unit => ({
  603.                 ...unit,
  604.                 product_name: product.name
  605.               }))
  606.             } else if (this.currentTab.value === 'delivered') {
  607.               const productsRequested = this.item.products_requested
  608.               product.units = product.delivered_units.map(unit => ({
  609.                 ...unit,
  610.                 price: productsRequested[product.product_id].units.find(val => val.unit_name === unit.unit_name).price,
  611.                 product_name: product.name
  612.               }))
  613.             } else if (this.currentTab.value === 'return') {
  614.               const productsRequested = this.item.products_requested
  615.               product.units = product.returned_units.map(unit => ({
  616.                 ...unit,
  617.                 price: productsRequested[product.product_id].units.find(val => val.unit_name === unit.unit_name).price,
  618.                 product_name: product.name
  619.               }))
  620.             }
  621.             for (const unit of product.units) {
  622.               unit.subtotal_price = unit.quantity * unit.price
  623.             }
  624.           }
  625.         })
  626.         return products
  627.       } else {
  628.         return null
  629.       }
  630.     },
  631.     isB2C () {
  632.       const item = this.salesOrderData
  633.       if (item) {
  634.         const createdUsing = item.created_using
  635.         if (['b2c_app'].includes(createdUsing)) {
  636.           return true
  637.         }
  638.       }
  639.       return false
  640.     },
  641.     currentDiscount () {
  642.       let returnValue = 0
  643.       const voucher = this.salesOrderData.voucher
  644.       if (
  645.         !voucher ||
  646.         !voucher.values
  647.       ) { return returnValue }
  648.       const initialTotalPrice = this.initialTotalPrice
  649.       return initialTotalPrice - this.currentTotalPrice
  650.     },
  651.     initialTotalPrice () {
  652.       const products = this.objectSelected
  653.       return Object.keys(products).reduce(
  654.         (sum, productId) => sum + products[productId].units.reduce(
  655.           (productSum, unit) => productSum + (unit.subtotal_price || 0)
  656.         , 0)
  657.       , 0)
  658.     },
  659.     currentTotalPrice () {
  660.       if (this.currentTab && _.has(this.salesOrderData, 'total_price_' + this.currentTab.value)) {
  661.         let price = parseInt(this.salesOrderData['total_price_' + this.currentTab.value])
  662.         if (_.isNumber(price) && !_.isNaN(price)) return price
  663.       }
  664.       return 0
  665.     }
  666.   },
  667.   methods: {
  668.     flattenProductUnitComposition (products) {
  669.       let flatProducts = []
  670.       for (let i = 0; i < products.length; i++) {
  671.         if (products[i].units.length < 2 && !products[i].hasOwnProperty('composite_items')) {
  672.           flatProducts.push({
  673.             ...products[i],
  674.             isCompositeChildren: false
  675.           })
  676.           continue
  677.         }
  678.         if (products[i].hasOwnProperty('composite_items')) {
  679.           flatProducts.push({
  680.             ...products[i],
  681.             isCompositeChildren: false
  682.           })
  683.           for (let j = 0; j < products[i].composite_items.length; j++) {
  684.             flatProducts.push({
  685.               ...products[i].composite_items[j],
  686.               isCompositeChildren: true
  687.             })
  688.           }
  689.           continue
  690.         }
  691.         for (let k = 0; k < products[i].units.length; k++) {
  692.           flatProducts.push({
  693.             ...products[i],
  694.             units: [
  695.               products[i].units[k]
  696.             ],
  697.             isCompositeChildren: false
  698.           })
  699.         }
  700.       }
  701.       return flatProducts
  702.     },
  703.     async fetchSalesOrders () {
  704.       this.fullscreenLoading = true
  705.       let temp = await this.$store.dispatch('sales/fetchSalesOrder', this.$route.params.id)
  706.       this.salesOrderData = JSON.parse(JSON.stringify(temp.data))
  707.       if (this.salesOrderData.hasOwnProperty('voucher')) {
  708.         this.voucher = JSON.parse(JSON.stringify(this.salesOrderData.voucher))
  709.       }
  710.       if (this.salesOrderData.hasOwnProperty('sales_exchange_id')) {
  711.         this.salesExchangeId = this.salesOrderData.sales_exchange_id
  712.         this.fetchSalesExchange()
  713.       }
  714.       this.fullscreenLoading = false
  715.     },
  716.     async fetchSalesExchange () {
  717.       let temp = await this.$store.dispatch('salesExchange/getSalesExchange', { salesExchangeId: this.salesExchangeId })
  718.       this.salesExchangeData = JSON.parse(JSON.stringify(temp.data))
  719.       console.log('temp2', temp)
  720.     },
  721.     renderMerchantName (soData) {
  722.       if (soData.merchant) return soData.merchant.store_name
  723.     },
  724.     renderOwnerName (soData) {
  725.       if (soData.merchant) return soData.merchant.owner_name
  726.     },
  727.     renderOwnerPhoneNumber (soData) {
  728.       if (soData.merchant) return soData.merchant.phone_number
  729.     },
  730.     renderMerchantAddress (soData) {
  731.       if (soData.merchant) return soData.merchant.address
  732.     },
  733.     renderMerchantcity (soData) {
  734.       if (soData.merchant && soData.merchant.detail_area) return soData.merchant.detail_area.city
  735.     },
  736.     renderMerchantPostcode (soData) {
  737.       if (soData.merchant && soData.merchant.detail_area) return soData.merchant.detail_area.post_code
  738.     },
  739.     renderOperationHour (soData) {
  740.       if (soData.merchant) return `${soData.merchant.opening_hours} - ${soData.merchant.closing_hours}`
  741.     },
  742.     renderSalesName (soData) {
  743.       if (soData.merchant) return soData.merchant.sales_name
  744.     },
  745.     renderSalesPhoneNumber (soData) {
  746.       if (soData.merchant) return soData.merchant.sales_phone_number
  747.     },
  748.     renderMerchantPatokan (soData) {
  749.       if (soData.merchant) return soData.merchant.additional_information
  750.     },
  751.     renderDOStatus (soData) {
  752.       if (soData.status) return _(soData.status).capitalize()
  753.     },
  754.     renderOrderDate (soData) {
  755.       if (soData.requested_date_manual) return moment(soData.requested_date_manual).format('dddd, DD/MM/YYYY')
  756.     },
  757.     renderDeliveryDate (soData) {
  758.       if (soData.delivered_date) return moment.unix(soData.delivered_date._seconds).format('dddd, DD/MM/YY')
  759.     },
  760.     renderPaidDate (soData) {
  761.       if (soData.paid_at) return moment.unix(soData.paid_at._seconds).format('dddd, DD/MM/YY')
  762.     },
  763.     renderAdminNotes (soData) {
  764.       if (soData.admin_notes) return soData.admin_notes
  765.     },
  766.     renderVoucher (soData) {
  767.       if (soData.hasOwnProperty('voucher')) return soData.voucher.name
  768.     },
  769.     getVoucherType (soData) {
  770.       let returnValue = '-'
  771.       if (!soData.voucher || !soData.voucher.type) {
  772.         return returnValue
  773.       }
  774.       returnValue = soData.voucher.type
  775.       return _(returnValue || '-').capitalize().replace('_', ' ')
  776.     },
  777.     renderCode (soData) {
  778.       if (soData.hasOwnProperty('voucher')) return soData.voucher.code
  779.     },
  780.     getUniqueCodeValue () {
  781.       if (
  782.         !this.salesOrderData ||
  783.         !this.salesOrderData.payment_details ||
  784.         !this.salesOrderData.payment_details.unique_code
  785.       ) {
  786.         return 0
  787.       }
  788.       const uniqueCode = Number.parseInt(this.salesOrderData.payment_details.unique_code)
  789.       if (Number.isNaN(uniqueCode)) return 0
  790.       return uniqueCode
  791.     },
  792.     getTotalPrice () {
  793.       if (this.currentTab && this.currentTab.value === 'return') return this.currentTotalPrice
  794.       return this.currentTotalPrice + this.getUniqueCodeValue()
  795.     },
  796.     renderQuantitySE (quantity) {
  797.       if (quantity.requested) return quantity.requested
  798.     },
  799.     renderPayment (salesOrderData) {
  800.       if (salesOrderData.payment_details) return salesOrderData.payment_details.payment_type
  801.     },
  802.     renderPaymentStatus (salesOrderData) {
  803.       if (salesOrderData.payment_details) return _(salesOrderData.payment_details.status).capitalize()
  804.     },
  805.     renderPaymentDate (salesOrderData) {
  806.       if (salesOrderData.paid_at) return moment(salesOrderData.payment_details.expiry_date._seconds).format('dddd, DD/MM/YYYY')
  807.     }
  808.   }
  809. }
  810. </script>
  811. <style>
  812. * {
  813.   margin-top: 0;
  814. }
  815. .light-grey {
  816.   color: #aeaeae;
  817. }
  818. #table-detail-order-fulfill {
  819.   border-collapse: collapse;
  820. }
  821. .table-row-underline {
  822.   border-bottom: 1px solid #e3e3e3;
  823. }
  824. .v-tabs .v-tabs__slider.custom-green {
  825.   height: 4px;
  826.   background-color: #4cb050 !important;
  827.   border-color: #4cb050 !important;
  828. }
  829. </style>
  830.  
  831.  

Editor

You can edit this paste and save as new:


File Description
  • SalesOrdersDetail.vue
  • Paste Code
  • 14 Apr-2021
  • 33.65 Kb
You can Share it: