[javascript] PPOB

Viewer

  1. <template>
  2.   <v-layout column fill-height justify-start>
  3.     <!-- TITLE ADD PRODUCT -->
  4.     <!-- https://wtools.io/paste-code/b52F -->
  5.     <v-snackbar
  6.       :color="snackbar.color"
  7.       v-model="snackbar.value"
  8.       multi-line
  9.       top
  10.     >
  11.       {{snackbar.text}}
  12.       <v-btn dark flat @click.native="snackbar.value = false">Close</v-btn>
  13.     </v-snackbar>
  14.     <v-flex>
  15.       <v-layout row>
  16.         <v-flex>
  17.           <div class="title font-weight-bold">
  18.             Add Product {{ this.pageTitle }}
  19.           </div>
  20.         </v-flex>
  21.       </v-layout>
  22.     </v-flex>
  23.     <!-- END TITLE ADD PRODUCT  -->
  24.  
  25.     <!-- V-card -->
  26.     <v-flex xs12 md12 pt-3>
  27.       <v-layout row>
  28.         <v-flex>
  29.           <v-stepper v-model="stepper" class="elevation-2">
  30.             <v-stepper-header class="elevation-0">
  31.               <v-stepper-step :complete="stepper > 1" step="1">Product Information</v-stepper-step>
  32.               <v-divider></v-divider>
  33.               <v-stepper-step step="2">Unit Information</v-stepper-step>
  34.             </v-stepper-header>
  35.             <v-divider></v-divider>
  36.             <v-stepper-items>
  37.               <v-stepper-content step="1">
  38.                 <v-form v-model="valid" ref="pricelistForm">
  39.                   <v-flex class="py-2 mb-5" lg12 md12 sm12 xs12>
  40.                     <v-container grid-list-md fluid pa-0>
  41.                       <v-layout column>
  42.                         <v-flex>
  43.                           <v-layout row wrap>
  44.                             <v-flex xs12 sm3 class="subheading font-weight-bold">
  45.                               Product Information
  46.                             </v-flex>
  47.                             <v-flex xs12 sm4>
  48.                               <label for="business_unit" class="subheading">Product ID<span class="red--text">*</span></label>
  49.                               <v-text-field required v-model="idProduct" :rules="[idRules(idProduct)]" label="Product Id Klikdaily" solo class="solo-outline" :disabled="isEditMode"></v-text-field>
  50.                             </v-flex>
  51.                             <v-flex xs12 offset-sm3 sm6>
  52.                               <label id="product-name" for="distribution_centre" class="subheading">Product Name</label>
  53.                               <v-text-field required v-model="productName" label="(ex. Pulsa Telkomsel 20.000)" solo class="solo-outline"></v-text-field>
  54.                             </v-flex>
  55.                             <v-flex xs12 offset-sm3 sm6>
  56.                               <label class="subheading">Description</label>
  57.                               <vueditor ref="descriptionEditor"></vueditor>
  58.                             </v-flex>
  59.                           </v-layout>
  60.                         </v-flex>
  61.                       </v-layout>
  62.                     </v-container>
  63.                   </v-flex>
  64.                 </v-form>
  65.                 <v-divider class="pt-3"></v-divider>
  66.                 <v-card-actions class="pb-4 pr-4">
  67.                   <v-spacer></v-spacer>
  68.                   <v-btn @click="cancel()" flat color="secondary">Cancel</v-btn>
  69.                   <v-btn :disabled="isNextButtonDisabled" @click="stepper = 2" depressed color="success">Next</v-btn>
  70.                 </v-card-actions>
  71.               </v-stepper-content>
  72.               <v-stepper-content step="2">
  73.                 <v-flex class="py-2 mb-5" lg12 md12 sm12 xs12>
  74.                   <v-container grid-list-md fluid pa-0>
  75.                     <v-layout column>
  76.                       <v-flex>
  77.                         <v-layout row wrap>
  78.                           <v-flex xs12 sm3 class="subheading font-weight-bold">
  79.                             Product Prices
  80.                           </v-flex>
  81.                           <v-flex xs12 sm9>
  82.                             <v-layout row wrap>
  83.                               <v-flex sm1></v-flex>
  84.                               <v-flex sm3>
  85.                                 <label for="business_unit" class="subheading font-weight-bold">KDR101 - {{ productName }}<span class="red--text">*</span></label>
  86.                               </v-flex>
  87.                             </v-layout>
  88.                             <v-layout row wrap v-for="(productPrice, index) in productPrices" :key="index">
  89.                               <v-flex sm1 v-if="index > 0" class="text-xs-right">
  90.                                 <v-icon 
  91.                                   color="red"
  92.                                   class="pt-4 mt-2"
  93.                                 >
  94.                                   remove_circle
  95.                                 </v-icon>
  96.                               </v-flex>
  97.                               <v-flex sm1 v-else>
  98.  
  99.                               </v-flex>
  100.                               <v-flex sm3>
  101.                                 <label for="business_unit" class="subheading">Select Vendor</label>
  102.                                 <v-autocomplete
  103.                                   solo
  104.                                   class="solo-outline"
  105.                                   :items="vendors"
  106.                                   return-object
  107.                                   v-model="vendorSelected"
  108.                                   item-value="id"
  109.                                   @change="fetchProductIdVendor(vendorSelected)"
  110.                                   :filter="autocompleteFilter"
  111.                                 >
  112.                                   <template v-slot:selection="data">
  113.                                     {{ data.item.name }}
  114.                                   </template>
  115.                                   <template v-slot:item="data">
  116.                                     {{ data.item.name }}
  117.                                   </template>
  118.                                 </v-autocomplete>
  119.                               </v-flex>
  120.                               <v-flex sm3>
  121.                                 <label for="business_unit" class="subheading">Product Id Vendor<span class="red--text">*</span></label>
  122.                                 <v-autocomplete
  123.                                   :loading="fetchVendorLoading"
  124.                                   solo
  125.                                   class="solo-outline"
  126.                                   :items="vendorDetailProducts"
  127.                                   return-object
  128.                                   v-model="vendorDetailProductSelected"
  129.                                   item-value="id"
  130.                                   :filter="autocompleteFilter"
  131.                                 >
  132.                                   <template v-slot:selection="data">
  133.                                     {{ data.item.name }}
  134.                                   </template>
  135.                                   <template v-slot:item="data">
  136.                                     {{ data.item.name }}
  137.                                   </template>
  138.                                 </v-autocomplete>
  139.                               </v-flex>
  140.                               <v-flex sm3>
  141.                                 <label for="business_unit" class="subheading">Buying Price</label>
  142.                                 <v-currency-field
  143.                                   solo
  144.                                   class="solo-outline"
  145.                                   :prefix="'Rp'"
  146.                                   type="number"
  147.                                   disabled
  148.                                   :decimal-length="0"
  149.                                   v-model.number="vendorDetailProductSelected.purchase_price"
  150.                                   label="Price"
  151.                                 ></v-currency-field>
  152.                               </v-flex>
  153.                               <v-flex sm2>
  154.                                 <label for="business_unit" class="subheading">Price Status</label>
  155.                                 <v-switch
  156.                                   v-model="priceStatus"
  157.                                   :label="`${priceStatus ? 'Active' : 'Inactive'}`"
  158.                                   color="primary"
  159.                                 ></v-switch>
  160.                               </v-flex>
  161.                             </v-layout>
  162.                           </v-flex>
  163.                           <v-flex xs12 sm3></v-flex>
  164.                           <v-flex xs12 sm4 ml-5 pl-4>
  165.                             <v-btn color="warning" @click="addNewProduct()">Assign New Product</v-btn>
  166.                           </v-flex>
  167.                           <v-flex sm5></v-flex>
  168.                           <v-flex xs12 sm12>
  169.                             <v-divider></v-divider>
  170.                           </v-flex>
  171.                           <v-flex>
  172.                             <v-layout row wrap>
  173.                               <v-flex xs12 sm3 class="subheading font-weight-bold">
  174.                                 Selling Price
  175.                               </v-flex>
  176.                               <v-flex xs12 sm9>
  177.                                 <v-layout row wrap>
  178.                                   <v-flex sm1></v-flex>
  179.                                   <v-flex sm3>
  180.                                     <label for="business_unit" class="subheading">Selling Price</label>
  181.                                   </v-flex>
  182.                                 </v-layout>
  183.                                 <v-layout row wrap>
  184.                                   <v-flex sm1></v-flex>
  185.                                   <v-flex sm3>
  186.                                     <v-currency-field
  187.                                       solo
  188.                                       class="solo-outline"
  189.                                       :prefix="'Rp'"
  190.                                       type="number"
  191.                                       :decimal-length="0"
  192.                                       v-model.number="sellingPrice"
  193.                                       label="Price"
  194.                                     ></v-currency-field>
  195.                                   </v-flex>
  196.                                 </v-layout>
  197.                               </v-flex>
  198.                             </v-layout>
  199.                           </v-flex>
  200.                         </v-layout>
  201.                       </v-flex>
  202.                     </v-layout>
  203.                   </v-container>
  204.                 </v-flex>
  205.                 <v-divider class="mb-3"></v-divider>
  206.                 <v-card-actions class="pb-4 pr-4">
  207.                   <v-spacer></v-spacer>
  208.                   <v-btn @click="stepper = 1" flat color="secondary">Previous</v-btn>
  209.                   <v-btn @click="confirmModal()" depressed color="success">Confirm</v-btn>
  210.                 </v-card-actions>
  211.               </v-stepper-content>
  212.             </v-stepper-items>
  213.           </v-stepper>
  214.         </v-flex>
  215.       </v-layout>
  216.     </v-flex>
  217.     <!-- end v-card -->
  218.   </v-layout>
  219. </template>
  220.  
  221. <script>
  222. import Vue from 'vue'
  223. import VeeValidate from 'vee-validate'
  224. import Vuex from 'vuex'
  225. // import 'vueditor/dist/style/vueditor.min.css'
  226. import Vueditor from 'vueditor'
  227.  
  228. let config = {
  229.   // for vueeditor
  230.   toolbar: [
  231.     'bold', 'italic', 'underline', '|',
  232.     'justifyLeft', 'justifyCenter', 'justifyRight', '|',
  233.     'insertOrderedList', 'insertUnorderedList', '|',
  234.     'undo', 'redo', '|',
  235.     'link'
  236.   ]
  237. }
  238.  
  239. Vue.use(VeeValidate, {fieldsBagName: 'vvFields'})
  240. Vue.use(Vuex)
  241. Vue.use(Vueditor, config)
  242.  
  243. export default {
  244.   $_veeValidate: {
  245.     validator: 'new'
  246.   },
  247.   components: {
  248.     ValidationProvider: VeeValidate.ValidationProvider
  249.   },
  250.   data: () => ({
  251.     vendorSelected: {},
  252.     productPrices: [
  253.       {
  254.         vendorSelected: {},
  255.         vendorDetailProductSelected: {},
  256.         purchasePrice: 0,
  257.         priceStatus: true
  258.       }
  259.     ],
  260.     pageTitle: '',
  261.     priceStatus: true,
  262.     idProduct: '',
  263.     productName: '',
  264.     description: '',
  265.     stepper: 0,
  266.     valid: true,
  267.     sellingPrice: '',
  268.     fetchVendorLoading: false,
  269.     vendors: [],
  270.     vendorDetailProducts: [],
  271.     vendorDetailProductSelected: {},
  272.     snackbar: {
  273.       value: false,
  274.       text: '',
  275.       color: 'primary'
  276.     }
  277.   }),
  278.   created () {
  279.     this.definePageTitle()
  280.     this.fetchPPOBVendors()
  281.   },
  282.   watch: {
  283.     descriptionEditorContent (newValue) {
  284.       this.description = newValue
  285.     }
  286.   },
  287.   computed: {
  288.     descriptionEditorContent: {
  289.       get () {
  290.         if (`${this.mode}`.length > 0) {
  291.           return this.$refs.descriptionEditor.getContent()
  292.         }
  293.         return null
  294.       },
  295.       set (newContent) {
  296.         this.$refs.descriptionEditor.setContent(newContent)
  297.       }
  298.     },
  299.     isEditMode () {
  300.       return this.mode === 'edit'
  301.     },
  302.     isNextButtonDisabled () {
  303.       if (!this.idProduct) {
  304.         return true
  305.       } else return false
  306.     }
  307.   },
  308.   methods: {
  309.     autocompleteFilter (item, queryText, itemText) {
  310.       const actualItemName = item.name || item.category_name
  311.       const mainText = actualItemName.toLowerCase()
  312.       const searchText = queryText.toLowerCase()
  313.  
  314.       return mainText.indexOf(searchText) > -1
  315.     },
  316.     addNewProduct () {
  317.       this.productPrices.push({
  318.         vendorSelected: {},
  319.         vendorDetailProductSelected: {},
  320.         purchasePrice: 0,
  321.         priceStatus: true
  322.       })
  323.     },
  324.     removeProduct () {
  325.       this.productPrices.splice()
  326.     },
  327.     definePageTitle () {
  328.       if (this.$route.params.type === 'mobile_credit') this.pageTitle = 'Pulsa'
  329.       else if (this.$route.params.type === 'mobile_package') this.pageTitle = 'Paket Data'
  330.       else if (this.$route.params.type === 'prepaid_electricity') this.pageTitle = 'Listrik'
  331.     },
  332.     cancel () {
  333.       this.$router.push(`/ppob-list/${this.$route.params.type}/detail/${this.$route.params.id}/products`)
  334.     },
  335.     confirmModal () {
  336.       console.log('confirm')
  337.     },
  338.     idRules (idProduct) {
  339.       if (idProduct) {
  340.         return true
  341.       } else {
  342.         return 'This field is required'
  343.       }
  344.     },
  345.     async fetchPPOBVendors () {
  346.       this.loading = true
  347.       await this.$store.dispatch('ppob/fetchPPOBVendors').then(result => {
  348.         if (result.status === 200) {
  349.           this.$set(this, 'vendors', result.data)
  350.           this.loading = false
  351.         } else {
  352.           this.snackbar.value = true
  353.           this.snackbar.text = result.message
  354.           this.snackbar.color = 'error'
  355.           this.loading = false
  356.         }
  357.       }).catch(error => {
  358.         this.snackbar.value = true
  359.         this.snackbar.text = error.message
  360.         this.snackbar.color = 'error'
  361.         this.loading = false
  362.       })
  363.     },
  364.     async fetchProductIdVendor (vendorProductSelected) {
  365.       console.log('vendor Product Selected', vendorProductSelected)
  366.       this.fetchVendorLoading = true
  367.       let params = {
  368.         idvendor: vendorProductSelected.id
  369.       }
  370.       await this.$store.dispatch('ppob/fetchPPOBVendorProducts', params).then(result => {
  371.         if (result.status === 200) {
  372.           this.$set(this, 'vendorDetailProducts', result.data)
  373.           this.loading = false
  374.         } else {
  375.           this.snackbar.value = true
  376.           this.snackbar.text = result.message
  377.           this.snackbar.color = 'error'
  378.           this.loading = false
  379.         }
  380.         this.fetchVendorLoading = false
  381.       }).catch(error => {
  382.         this.snackbar.value = true
  383.         this.snackbar.text = error.message
  384.         this.snackbar.color = 'error'
  385.         this.loading = false
  386.       })
  387.     }
  388.   }
  389. }
  390. </script>
  391.  

Editor

You can edit this paste and save as new: