[javascript] ppob.vue
Viewer
*** This page was generated with the meta tag "noindex, nofollow". This happened because you selected this option before saving or the system detected it as spam. This means that this page will never get into the search engines and the search bot will not crawl it. There is nothing to worry about, you can still share it with anyone.
- <template>
- <v-layout column fill-height justify-start>
- <!-- TITLE ADD PRODUCT -->
- <v-snackbar
- :color="snackbar.color"
- v-model="snackbar.value"
- multi-line
- top
- >
- {{snackbar.text}}
- <v-btn dark flat @click.native="snackbar.value = false">Close</v-btn>
- </v-snackbar>
- <v-flex>
- <v-layout row>
- <v-flex>
- <div class="title font-weight-bold">
- Add Product {{ this.pageTitle }}
- </div>
- </v-flex>
- </v-layout>
- </v-flex>
- <!-- END TITLE ADD PRODUCT -->
- <!-- V-card -->
- <v-flex xs12 md12 pt-3>
- <v-layout row>
- <v-flex>
- <v-stepper v-model="stepper" class="elevation-2">
- <v-stepper-header class="elevation-0">
- <v-stepper-step :complete="stepper > 1" step="1">Product Information</v-stepper-step>
- <v-divider></v-divider>
- <v-stepper-step step="2">Unit Information</v-stepper-step>
- </v-stepper-header>
- <v-divider></v-divider>
- <v-stepper-items>
- <v-stepper-content step="1">
- <v-form v-model="valid" ref="pricelistForm">
- <v-flex class="py-2 mb-5" lg12 md12 sm12 xs12>
- <v-container grid-list-md fluid pa-0>
- <v-layout column>
- <v-flex>
- <v-layout row wrap>
- <v-flex xs12 sm3 class="subheading font-weight-bold">
- Product Information
- </v-flex>
- <v-flex xs12 sm4>
- <label for="business_unit" class="subheading">Product ID<span class="red--text">*</span></label>
- <v-text-field required v-model="idProduct" :rules="[idRules(idProduct)]" label="Product Id Klikdaily" solo class="solo-outline" :disabled="isEditMode"></v-text-field>
- </v-flex>
- <v-flex xs12 offset-sm3 sm6>
- <label id="product-name-provider-add-product" for="distribution_centre" class="subheading">Product Name</label>
- <v-text-field required v-model="productName" label="(ex. Pulsa Telkomsel 20.000)" solo class="solo-outline"></v-text-field>
- </v-flex>
- <v-flex xs12 offset-sm3 sm6>
- <label class="subheading">Description</label>
- <vueditor ref="descriptionEditor"></vueditor>
- </v-flex>
- </v-layout>
- </v-flex>
- </v-layout>
- </v-container>
- </v-flex>
- </v-form>
- <v-divider class="pt-3"></v-divider>
- <v-card-actions class="pb-4 pr-4">
- <v-spacer></v-spacer>
- <v-btn @click="cancel()" flat color="secondary">Cancel</v-btn>
- <v-btn :disabled="isNextButtonDisabled" @click="stepper = 2" depressed color="success">Next</v-btn>
- </v-card-actions>
- </v-stepper-content>
- <v-stepper-content step="2">
- <v-flex class="py-2 mb-5" lg12 md12 sm12 xs12>
- <v-container grid-list-md fluid pa-0>
- <v-layout column>
- <v-flex>
- <v-layout row wrap>
- <v-flex xs12 sm3 class="subheading font-weight-bold">
- Product Prices
- </v-flex>
- <v-flex xs12 sm9>
- <v-layout row wrap>
- <v-flex sm1></v-flex>
- <v-flex sm3>
- <label for="business_unit" class="subheading font-weight-bold">{{ idProduct }} - {{ productName }}<span class="red--text">*</span></label>
- </v-flex>
- </v-layout>
- <v-layout row wrap v-for="(productPrice, index) in productPrices" :key="index">
- <v-flex sm1 v-if="index > 0" class="text-xs-right">
- <v-icon
- color="red"
- class="pt-4 mt-2"
- v-on:click="removeNewProduct(index)"
- >
- remove_circle
- </v-icon>
- </v-flex>
- <v-flex sm1 v-else>
- </v-flex>
- <v-flex sm3>
- <label for="business_unit" class="subheading">Select Vendor</label>
- <v-autocomplete
- solo
- class="solo-outline"
- :items="vendors"
- return-object
- v-model="productPrice.vendorSelected"
- item-value="id"
- @change="fetchProductIdVendor(productPrice.vendorSelected, index)"
- :filter="autocompleteFilter"
- >
- <template v-slot:selection="data">
- {{ data.item.name }}
- </template>
- <template v-slot:item="data">
- {{ data.item.name }}
- </template>
- </v-autocomplete>
- </v-flex>
- <v-flex sm3>
- <label for="business_unit" class="subheading">Product Id Vendor<span class="red--text">*</span></label>
- <v-autocomplete
- :loading="fetchVendorLoading"
- solo
- class="solo-outline"
- :items="productPrice.vendorDetailProducts"
- return-object
- v-model="productPrice.vendorDetailProductSelected"
- item-value="id"
- :filter="autocompleteFilter"
- >
- <template v-slot:selection="data">
- {{ data.item.name }}
- </template>
- <template v-slot:item="data">
- {{ data.item.name }}
- </template>
- </v-autocomplete>
- </v-flex>
- <v-flex sm3>
- <label for="business_unit" class="subheading">Buying Price</label>
- <v-currency-field
- solo
- class="solo-outline"
- :prefix="'Rp'"
- type="number"
- disabled
- :decimal-length="0"
- v-model.number="productPrice.vendorDetailProductSelected.purchase_price"
- label="Price"
- ></v-currency-field>
- </v-flex>
- <v-flex sm2>
- <label for="business_unit" class="subheading">Price Status</label>
- <v-switch
- v-model="priceStatus"
- :label="`${priceStatus ? 'Active' : 'Inactive'}`"
- color="primary"
- ></v-switch>
- </v-flex>
- </v-layout>
- </v-flex>
- <v-flex xs12 sm3></v-flex>
- <v-flex xs12 sm4 ml-5 pl-4>
- <v-btn color="warning" @click="addNewProduct()">Assign New Product</v-btn>
- </v-flex>
- <v-flex sm5></v-flex>
- <v-flex xs12 sm12>
- <v-divider></v-divider>
- </v-flex>
- <v-flex>
- <v-layout row wrap>
- <v-flex xs12 sm3 class="subheading font-weight-bold">
- Selling Price
- </v-flex>
- <v-flex xs12 sm9>
- <v-layout row wrap>
- <v-flex sm1></v-flex>
- <v-flex sm3>
- <label for="business_unit" class="subheading">Selling Price</label>
- </v-flex>
- </v-layout>
- <v-layout row wrap>
- <v-flex sm1></v-flex>
- <v-flex sm3>
- <v-currency-field
- solo
- class="solo-outline"
- :prefix="'Rp'"
- type="number"
- :decimal-length="0"
- v-model.number="sellingPrice"
- label="Price"
- ></v-currency-field>
- </v-flex>
- </v-layout>
- </v-flex>
- </v-layout>
- </v-flex>
- </v-layout>
- </v-flex>
- </v-layout>
- </v-container>
- </v-flex>
- <v-divider class="mb-3"></v-divider>
- <v-card-actions class="pb-4 pr-4">
- <v-spacer></v-spacer>
- <v-btn @click="stepper = 1" flat color="secondary">Previous</v-btn>
- <v-btn id="confirm-modal-add-product-provider" @click="confirmModal()" depressed color="success">Confirm</v-btn>
- </v-card-actions>
- </v-stepper-content>
- </v-stepper-items>
- </v-stepper>
- </v-flex>
- </v-layout>
- </v-flex>
- <!-- end v-card -->
- <!-- Dialog confirmation -->
- <v-dialog
- v-model="dialogConfirmation" persistent max-width="600px" transition="dialog-transition"
- >
- <v-card>
- <v-card-title>
- <h1 class="title font-weight-bold">{{ mode === 'new' ? 'Add' : 'Edit' }} Product</h1>
- </v-card-title>
- <v-divider></v-divider>
- <v-card-text>
- Are you sure {{ mode === 'new' ? 'Created' : 'Edit' }} Product "{{ pageTitle }} {{ productName }}"?
- </v-card-text>
- <v-divider></v-divider>
- <v-card-actions>
- <v-spacer></v-spacer>
- <v-btn color="dark" flat :disabled="loading === true" @click="closeDialogConfirmation()">Cancel</v-btn>
- <v-btn color="primary" flat :loading="loading === true" @click="submit()">Yes</v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- <!-- LOADING -->
- <v-dialog v-if="fullscreenLoading" v-model="fullscreenLoading" fullscreen full-width>
- <v-container fluid fill-height style="background-color: rgba(255, 255, 255, 0.5);">
- <v-layout justify-center align-center>
- <v-progress-circular
- indeterminate
- color="primary">
- </v-progress-circular>
- </v-layout>
- </v-container>
- </v-dialog>
- <!-- END LOADING -->
- </v-layout>
- </template>
- <script>
- import Vue from 'vue'
- import VeeValidate from 'vee-validate'
- import Vuex from 'vuex'
- // import 'vueditor/dist/style/vueditor.min.css'
- import Vueditor from 'vueditor'
- let config = {
- // for vueeditor
- toolbar: [
- 'bold', 'italic', 'underline', '|',
- 'justifyLeft', 'justifyCenter', 'justifyRight', '|',
- 'insertOrderedList', 'insertUnorderedList', '|',
- 'undo', 'redo', '|',
- 'link'
- ]
- }
- Vue.use(VeeValidate, {fieldsBagName: 'vvFields'})
- Vue.use(Vuex)
- Vue.use(Vueditor, config)
- export default {
- $_veeValidate: {
- validator: 'new'
- },
- components: {
- ValidationProvider: VeeValidate.ValidationProvider
- },
- data: () => ({
- vendorSelected: {},
- productPrices: [
- {
- vendorDetailProducts: [],
- vendorSelected: {},
- vendorDetailProductSelected: {},
- purchasePrice: 0,
- priceStatus: true
- }
- ],
- pageTitle: '',
- loading: false,
- mode: '',
- priceStatus: true,
- idProduct: '',
- productName: '',
- description: '',
- stepper: 0,
- valid: true,
- sellingPrice: '',
- fetchVendorLoading: false,
- vendors: [],
- vendorDetailProducts: [],
- vendorDetailProductSelected: {},
- dialogConfirmation: false,
- editPPOBProductDetail: {},
- fullscreenLoading: false,
- snackbar: {
- value: false,
- text: '',
- color: 'primary'
- }
- }),
- created () {
- this.defineMode()
- this.definePageTitle()
- this.fetchPPOBVendors()
- },
- watch: {
- descriptionEditorContent (newValue) {
- this.description = newValue
- }
- },
- computed: {
- descriptionEditorContent: {
- get () {
- if (`${this.mode}`.length > 0) {
- return this.$refs.descriptionEditor.getContent()
- }
- return null
- },
- set (newContent) {
- this.$refs.descriptionEditor.setContent(newContent)
- }
- },
- isEditMode () {
- return this.mode === 'edit'
- },
- isNextButtonDisabled () {
- if (!this.idProduct) {
- return true
- } else return false
- }
- },
- methods: {
- defineMode () {
- if (this.$route.params.id && this.$route.params.mode === 'edit') {
- this.mode = 'edit'
- this.fetchPPOBProductById()
- } else {
- this.mode = 'new'
- }
- },
- closeDialogConfirmation () {
- this.dialogConfirmation = false
- },
- paramsProductPricesForSubmit () {
- let result = []
- for (let i = 0; i < this.productPrices.length; i++) {
- result.push({
- product_id: this.productPrices[i].vendorDetailProductSelected.id,
- name: this.productPrices[i].vendorDetailProductSelected.name,
- price: this.productPrices[i].vendorDetailProductSelected.purchase_price,
- status: this.productPrices[i].vendorDetailProductSelected.status
- })
- }
- return result
- },
- async fetchPPOBProductById () {
- this.fullscreenLoading = true
- // console.log(this.$route.params.id_products)
- await this.$store.dispatch('ppob/getPPOBProduct', this.$route.params.id_products).then(result => {
- if (result.status === 200 || result.status === 201) {
- this.editPPOBProductDetail = JSON.parse(JSON.stringify(result.data))
- this.productName = this.editPPOBProductDetail.name
- this.descriptionEditorContent = this.editPPOBProductDetail.description
- this.description = this.editPPOBProductDetail.description
- this.sellingPrice = this.editPPOBProductDetail.price
- this.idProduct = this.editPPOBProductDetail.product_id
- this.editPPOBProductDetail.vendors.forEach((vendor, index) => {
- let tempVendorDetailProductSelected = {
- purchase_price: vendor.price,
- name: vendor.name,
- id: vendor.product_id
- }
- if (index === 0) {
- this.productPrices[index].vendorSelected = vendor
- this.productPrices[index].vendorDetailProductSelected = tempVendorDetailProductSelected
- this.productPrices[index].priceStatus = vendor.status
- } else if (index > 0) {
- this.productPrices.push({
- vendorSelected: vendor,
- vendorDetailProductSelected: tempVendorDetailProductSelected,
- priceStatus: true
- })
- }
- })
- this.fetchPPOBVendors()
- } else {
- this.snackbar = true
- this.snackbarText = result.message
- this.snackbarColor = 'error'
- this.loading = false
- }
- this.fullscreenLoading = false
- }).catch(error => {
- this.fullscreenLoading = false
- this.snackbar.value = true
- this.snackbar.text = error.message
- this.snackbar.color = 'error'
- this.loading = false
- })
- },
- async submit () {
- this.loading = true
- if (this.mode === 'new') {
- let params = {
- product_id: this.idProduct,
- name: this.productName,
- description: this.descriptionEditorContent,
- price: this.sellingPrice,
- type: 'mobile_credit',
- provider: this.$route.params.id,
- vendors: this.paramsProductPricesForSubmit()
- }
- // console.log('params', params)
- await this.$store.dispatch('ppob/addPPOBProducts', params).then(result => {
- if (result.status === 200 || result.status === 201) {
- this.$store.dispatch('ppob/setMessage', `Product ${this.productName} successfully created`)
- this.loading = false
- this.$router.push(`/ppob-list/${this.$route.params.type}/detail/${this.$route.params.id}/products`)
- } else {
- this.snackbar = true
- this.snackbarText = result.message
- this.snackbarColor = 'error'
- this.loading = false
- }
- }).catch(error => {
- this.snackbar.value = true
- this.snackbar.text = error.message
- this.snackbar.color = 'error'
- this.loading = false
- })
- } else if (this.mode === 'edit') {
- let params = {
- body: {
- name: this.productName,
- description: this.descriptionEditorContent,
- price: this.sellingPrice,
- vendors: this.paramsProductPricesForSubmit()
- },
- id: this.$route.params.id_products
- }
- this.loading = true
- await this.$store.dispatch('ppob/editPPOBProduct', params).then(result => {
- if (result.status === 200 || result.status === 201) {
- this.$store.dispatch('ppob/setMessage', `Vendor ${this.vendorName} successfully updated`)
- this.loading = false
- this.$router.push(`/ppob-list/${this.$route.params.type}/detail/${this.$route.params.id}/products`)
- } else {
- this.snackbar = true
- this.snackbarText = result.message
- this.snackbarColor = 'error'
- this.loading = false
- }
- }).catch(error => {
- this.snackbar.value = true
- this.snackbar.text = error.message
- this.snackbar.color = 'error'
- this.loading = false
- })
- }
- },
- autocompleteFilter (item, queryText, itemText) {
- const actualItemName = item.name || item.category_name
- const mainText = actualItemName.toLowerCase()
- const searchText = queryText.toLowerCase()
- return mainText.indexOf(searchText) > -1
- },
- addNewProduct () {
- this.productPrices.push({
- vendorSelected: {},
- vendorDetailProductSelected: {},
- purchasePrice: 0,
- priceStatus: true
- })
- },
- removeNewProduct (targetId) {
- this.productPrices = [
- ...this.productPrices.filter((productPrice, index) => {
- return index !== targetId
- })
- ]
- },
- removeProduct () {
- this.productPrices.splice()
- },
- definePageTitle () {
- if (this.$route.params.type === 'mobile_credit') this.pageTitle = 'Pulsa'
- else if (this.$route.params.type === 'mobile_package') this.pageTitle = 'Paket Data'
- else if (this.$route.params.type === 'prepaid_electricity') this.pageTitle = 'Listrik'
- },
- cancel () {
- this.$router.push(`/ppob-list/${this.$route.params.type}/detail/${this.$route.params.id}/products`)
- },
- confirmModal () {
- this.dialogConfirmation = true
- },
- idRules (idProduct) {
- if (idProduct) {
- return true
- } else {
- return 'This field is required'
- }
- },
- async fetchPPOBVendors () {
- this.loading = true
- await this.$store.dispatch('ppob/fetchPPOBVendors').then(result => {
- if (result.status === 200) {
- this.$set(this, 'vendors', result.data)
- this.loading = false
- } else {
- this.snackbar.value = true
- this.snackbar.text = result.message
- this.snackbar.color = 'error'
- this.loading = false
- }
- }).catch(error => {
- this.snackbar.value = true
- this.snackbar.text = error.message
- this.snackbar.color = 'error'
- this.loading = false
- })
- },
- async fetchProductIdVendor (vendorProductSelected, targetId = null) {
- this.fetchVendorLoading = true
- let params = {
- idvendor: vendorProductSelected.id
- }
- await this.$store.dispatch('ppob/fetchPPOBVendorProducts', params).then(result => {
- if (result.status === 200) {
- if (targetId === null) {
- this.$set(this, 'vendorDetailProducts', result.data)
- this.loading = false
- return
- }
- this.$set(this.productPrices[targetId], 'vendorDetailProducts', result.data)
- this.loading = false
- } else {
- this.snackbar.value = true
- this.snackbar.text = result.message
- this.snackbar.color = 'error'
- this.loading = false
- }
- this.fetchVendorLoading = false
- }).catch(error => {
- this.snackbar.value = true
- this.snackbar.text = error.message
- this.snackbar.color = 'error'
- this.loading = false
- })
- }
- }
- }
- </script>
Editor
You can edit this paste and save as new:
File Description
- ppob.vue
- Paste Code
- 15 Jun-2021
- 22.52 Kb
You can Share it:
Latest Code Pastes