관리-도구
편집 파일: edit_transfer.vue
<template> <div class="main-content"> <breadcumb :page="$t('EditTransfer')" :folder="$t('ListTransfers')"/> <div v-if="isLoading" class="loading_page spinner spinner-primary mr-3"></div> <validation-observer ref="Edit_transfer" v-if="!isLoading"> <b-form @submit.prevent="Submit_Transfer"> <b-row> <b-col lg="12" md="12" sm="12"> <b-card> <b-row> <b-modal hide-footer id="open_scan" size="md" title="Barcode Scanner"> <qrcode-scanner :qrbox="250" :fps="10" style="width: 100%; height: calc(100vh - 56px);" @result="onScan" /> </b-modal> <!-- date --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="date" :rules="{ required: true}" v-slot="validationContext" > <b-form-group :label="$t('date') + ' ' + '*'"> <b-form-input :state="getValidationState(validationContext)" aria-describedby="date-feedback" type="date" v-model="transfer.date" ></b-form-input> <b-form-invalid-feedback id="OrderTax-feedback" >{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- From warehouse --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="From Warehouse" :rules="{ required: true}"> <b-form-group slot-scope="{ valid, errors }" :label="$t('FromWarehouse') + ' ' + '*'"> <v-select :class="{'is-invalid': !!errors.length}" :state="errors[0] ? false : (valid ? true : null)" :disabled="details.length > 0" @input="Selected_From_Warehouse" v-model="transfer.from_warehouse" :reduce="label => label.value" :placeholder="$t('Choose_Warehouse')" :options="warehouses.map(warehouses => ({label: warehouses.name, value: warehouses.id}))" /> <b-form-invalid-feedback>{{ errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- To warehouse --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="To Warehouse" :rules="{ required: true}"> <b-form-group slot-scope="{ valid, errors }" :label="$t('ToWarehouse') + ' ' + '*'"> <v-select :class="{'is-invalid': !!errors.length}" :state="errors[0] ? false : (valid ? true : null)" v-model="transfer.to_warehouse" :reduce="label => label.value" :placeholder="$t('Choose_Warehouse')" :options="to_warehouses.map(to_warehouses => ({label: to_warehouses.name, value: to_warehouses.id}))" /> <b-form-invalid-feedback>{{ errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Product --> <b-col md="12" class="mb-5"> <h6>{{$t('ProductName')}}</h6> <div id="autocomplete" class="autocomplete"> <div class="input-with-icon"> <img src="/assets_setup/scan.png" alt="Scan" class="scan-icon" @click="showModal"> <input :placeholder="$t('Scan_Search_Product_by_Code_Name')" @input='e => search_input = e.target.value' @keyup="search(search_input)" @focus="handleFocus" @blur="handleBlur" ref="product_autocomplete" class="autocomplete-input" /> </div> <ul class="autocomplete-result-list" v-show="focused"> <li class="autocomplete-result" v-for="product_fil in product_filter" @mousedown="SearchProduct(product_fil)">{{getResultValue(product_fil)}}</li> </ul> </div> </b-col> <!-- details --> <b-col md="12"> <div class="table-responsive"> <table class="table table-hover"> <thead class="bg-gray-300"> <tr> <th scope="col">#</th> <th scope="col">{{$t('ProductName')}}</th> <th scope="col">{{$t('Net_Unit_Cost')}}</th> <th scope="col">{{$t('CurrentStock')}}</th> <th scope="col">{{$t('Qty')}}</th> <th scope="col">{{$t('Discount')}}</th> <th scope="col">{{$t('Tax')}}</th> <th scope="col">{{$t('SubTotal')}}</th> <th scope="col" class="text-center"> <i class="fa fa-trash"></i> </th> </tr> </thead> <tbody> <tr v-if="details.length <=0"> <td colspan="9">{{$t('NodataAvailable')}}</td> </tr> <tr v-for="detail in details" :class="{'row_deleted': detail.del === 1 || detail.no_unit === 0}" :key="detail.detail_id" > <td>{{detail.detail_id}}</td> <td> <span>{{detail.code}}</span> <br> <span class="badge badge-success">{{detail.name}}</span> <i v-show="detail.no_unit !== 0" @click="Modal_Updat_Detail(detail)" class="i-Edit"></i> </td> <td>{{currentUser.currency}} {{formatNumber(detail.Net_cost, 3)}}</td> <td> <span class="badge badge-outline-warning" >{{detail.stock}} {{detail.unitPurchase}}</span> </td> <td> <div class="quantity"> <b-input-group> <b-input-group-prepend> <span v-show="detail.no_unit !== 0" class="btn btn-primary btn-sm" @click="decrement(detail ,detail.detail_id)" >-</span> </b-input-group-prepend> <input class="form-control" @keyup="Verified_Qty(detail,detail.detail_id)" v-model.number="detail.quantity" :disabled="detail.del === 1 || detail.no_unit === 0" > <b-input-group-append> <span v-show="detail.no_unit !== 0" class="btn btn-primary btn-sm" @click="increment(detail ,detail.detail_id)" >+</span> </b-input-group-append> </b-input-group> </div> </td> <td>{{currentUser.currency}} {{formatNumber(detail.DiscountNet * detail.quantity, 2)}}</td> <td>{{currentUser.currency}} {{formatNumber(detail.taxe * detail.quantity , 2)}}</td> <td>{{currentUser.currency}} {{detail.subtotal.toFixed(2)}}</td> <td> <a v-show="detail.no_unit !== 0" @click="delete_Product_Detail(detail.detail_id)" class="btn btn-icon btn-sm" title="Delete" > <i class="i-Close-Window text-25 text-danger"></i> </a> </td> </tr> </tbody> </table> </div> </b-col> <div class="offset-md-9 col-md-3 mt-4"> <table class="table table-striped table-sm"> <tbody> <tr> <td class="bold">{{$t('OrderTax')}}</td> <td> <span>{{currentUser.currency}} {{transfer.TaxNet.toFixed(2)}} ({{formatNumber(transfer.tax_rate ,2)}} %)</span> </td> </tr> <tr> <td class="bold">{{$t('Discount')}}</td> <td>{{currentUser.currency}} {{transfer.discount.toFixed(2)}}</td> </tr> <tr> <td class="bold">{{$t('Shipping')}}</td> <td>{{currentUser.currency}} {{transfer.shipping.toFixed(2)}}</td> </tr> <tr> <td> <span class="font-weight-bold">{{$t('Total')}}</span> </td> <td> <span class="font-weight-bold" >{{currentUser.currency}} {{GrandTotal.toFixed(2)}}</span> </td> </tr> </tbody> </table> </div> <!-- Order Tax --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="Order Tax" :rules="{ regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('OrderTax')"> <b-input-group append="%"> <b-form-input :state="getValidationState(validationContext)" aria-describedby="OrderTax-feedback" label="Order Tax" v-model.number="transfer.tax_rate" @keyup="keyup_OrderTax()" ></b-form-input> </b-input-group> <b-form-invalid-feedback id="OrderTax-feedback" >{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Discount --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="Discount" :rules="{ regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('Discount')"> <b-input-group :append="currentUser.currency"> <b-form-input :state="getValidationState(validationContext)" aria-describedby="Discount-feedback" label="Discount" v-model.number="transfer.discount" @keyup="keyup_Discount()" ></b-form-input> </b-input-group> <b-form-invalid-feedback id="Discount-feedback" >{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Shipping --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="Shipping" :rules="{ regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('Shipping')"> <b-input-group :append="currentUser.currency"> <b-form-input :state="getValidationState(validationContext)" aria-describedby="Shipping-feedback" label="Shipping" v-model.number="transfer.shipping" @keyup="keyup_Shipping()" ></b-form-input> </b-input-group> <b-form-invalid-feedback id="Shipping-feedback" >{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Status --> <b-col lg="4" md="4" sm="12" class="mb-3"> <validation-provider name="Status" :rules="{ required: true}"> <b-form-group slot-scope="{ valid, errors }" :label="$t('Status') + ' ' + '*'"> <v-select :class="{'is-invalid': !!errors.length}" :state="errors[0] ? false : (valid ? true : null)" v-model="transfer.statut" :reduce="label => label.value" :placeholder="$t('Choose_Status')" :options=" [{label: 'Completed', value: 'completed'}, {label: 'Sent', value: 'sent'}, {label: 'Pending', value: 'pending'} ]" ></v-select> <b-form-invalid-feedback>{{ errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <b-col md="12"> <b-form-group :label="$t('Note')"> <textarea v-model="transfer.notes" rows="4" class="form-control" :placeholder="$t('Afewwords')" ></textarea> </b-form-group> </b-col> <b-col md="12"> <b-form-group> <b-button variant="primary" @click="Submit_Transfer" :disabled="SubmitProcessing"><i class="i-Yes me-2 font-weight-bold"></i> {{$t('submit')}}</b-button> <div v-once class="typo__p" v-if="SubmitProcessing"> <div class="spinner sm spinner-primary mt-3"></div> </div> </b-form-group> </b-col> </b-row> </b-card> </b-col> </b-row> </b-form> </validation-observer> <!-- Modal Update Detail Product --> <validation-observer ref="Update_Detail_transfer"> <b-modal hide-footer size="md" id="form_Update_Detail" :title="detail.name"> <b-form @submit.prevent="submit_Update_Detail"> <b-row> <!-- Unit Cost --> <b-col lg="12" md="12" sm="12"> <validation-provider name="Product Cost" :rules="{ required: true , regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('ProductCost') + ' ' + '*'" id="cost-input"> <b-form-input label="Product Cost" v-model.number="detail.Unit_cost" :state="getValidationState(validationContext)" aria-describedby="cost-feedback" ></b-form-input> <b-form-invalid-feedback id="cost-feedback">{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Tax Method --> <b-col lg="12" md="12" sm="12"> <validation-provider name="Tax Method" :rules="{ required: true}"> <b-form-group slot-scope="{ valid, errors }" :label="$t('TaxMethod') + ' ' + '*'"> <v-select :class="{'is-invalid': !!errors.length}" :state="errors[0] ? false : (valid ? true : null)" v-model="detail.tax_method" :reduce="label => label.value" :placeholder="$t('Choose_Method')" :options=" [ {label: 'Exclusive', value: '1'}, {label: 'Inclusive', value: '2'} ]" ></v-select> <b-form-invalid-feedback>{{ errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Tax Rate --> <b-col lg="12" md="12" sm="12"> <validation-provider name="Order Tax" :rules="{ required: true , regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('OrderTax') + ' ' + '*'"> <b-input-group append="%"> <b-form-input label="Order Tax" v-model.number="detail.tax_percent" :state="getValidationState(validationContext)" aria-describedby="OrderTax-feedback" ></b-form-input> </b-input-group> <b-form-invalid-feedback id="OrderTax-feedback">{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Discount Method --> <b-col lg="12" md="12" sm="12"> <validation-provider name="Discount Method" :rules="{ required: true}"> <b-form-group slot-scope="{ valid, errors }" :label="$t('Discount_Method') + ' ' + '*'"> <v-select v-model="detail.discount_Method" :reduce="label => label.value" :placeholder="$t('Choose_Method')" :class="{'is-invalid': !!errors.length}" :state="errors[0] ? false : (valid ? true : null)" :options=" [ {label: 'Percent %', value: '1'}, {label: 'Fixed', value: '2'} ]" ></v-select> <b-form-invalid-feedback>{{ errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <!-- Discount Rate --> <b-col lg="12" md="12" sm="12"> <validation-provider name="Discount Rate" :rules="{ required: true , regex: /^\d*\.?\d*$/}" v-slot="validationContext" > <b-form-group :label="$t('Discount') + ' ' + '*'"> <b-form-input label="Discount" v-model.number="detail.discount" :state="getValidationState(validationContext)" aria-describedby="Discount-feedback" ></b-form-input> <b-form-invalid-feedback id="Discount-feedback">{{ validationContext.errors[0] }}</b-form-invalid-feedback> </b-form-group> </validation-provider> </b-col> <b-col md="12"> <b-form-group> <b-button variant="primary" type="submit"><i class="i-Yes me-2 font-weight-bold"></i> {{$t('submit')}}</b-button> </b-form-group> </b-col> </b-row> </b-form> </b-modal> </validation-observer> </div> </template> <script> import { mapActions, mapGetters } from "vuex"; import NProgress from "nprogress"; export default { metaInfo: { title: "Update Transfer" }, data() { return { focused: false, timer:null, search_input:'', product_filter:[], isLoading: true, SubmitProcessing:false, details: [], detail: { quantity: "", discount: "", Unit_cost: "", discount_Method: "", tax_percent: "", tax_method: "" }, warehouses: [], to_warehouses: [], products: [], total: 0, GrandTotal: 0, transfer: { id: "", from_warehouse: "", to_warehouse: "", statut: "", notes: "", items: "", date:'', tax_rate: 0, TaxNet: 0, shipping: 0, discount: 0 }, product: { id: "", code: "", stock: "", quantity: "", discount: "", DiscountNet: "", discount_Method: "", name: "", no_unit:"", unitPurchase: "", purchase_unit_id: "", Net_cost: "", Unit_cost: "", Total_cost: "", subtotal: "", product_id: "", detail_id: "", taxe: "", tax_percent: "", tax_method: "", product_variant_id: "", etat: "" } }; }, computed: { ...mapGetters(["currentUser"]) }, methods: { handleFocus() { this.focused = true }, handleBlur() { this.focused = false }, showModal() { this.$bvModal.show('open_scan'); }, onScan (decodedText, decodedResult) { const code = decodedText; this.search_input = code; this.search(); this.$bvModal.hide('open_scan'); }, //------------- Submit Validation Update Transfer Submit_Transfer() { this.$refs.Edit_transfer.validate().then(success => { if (!success) { this.makeToast( "danger", this.$t("Please_fill_the_form_correctly"), this.$t("Failed") ); } else { this.Update_Transfer(); } }); }, //---Submit Validation Update Detail submit_Update_Detail() { this.$refs.Update_Detail_transfer.validate().then(success => { if (!success) { return; } else { this.Update_Detail(); } }); }, //---Validate State Fields getValidationState({ dirty, validated, valid = null }) { return dirty || validated ? valid : null; }, //---------- Show Modal Update Detail Product Modal_Updat_Detail(detail) { this.detail = {}; this.detail.name = detail.name; this.detail.detail_id = detail.detail_id; this.detail.Unit_cost = detail.Unit_cost; this.detail.tax_method = detail.tax_method; this.detail.discount_Method = detail.discount_Method; this.detail.discount = detail.discount; this.detail.quantity = detail.quantity; this.detail.tax_percent = detail.tax_percent; this.$bvModal.show("form_Update_Detail"); }, //---------- Submit Update Detail Product Update_Detail() { for (var i = 0; i < this.details.length; i++) { if (this.details[i].detail_id === this.detail.detail_id) { this.details[i].tax_percent = this.detail.tax_percent; this.details[i].Unit_cost = this.detail.Unit_cost; this.details[i].quantity = this.detail.quantity; this.details[i].tax_method = this.detail.tax_method; this.details[i].discount_Method = this.detail.discount_Method; this.details[i].discount = this.detail.discount; if (this.details[i].discount_Method == "2") { //Fixed this.details[i].DiscountNet = this.detail.discount; } else { //Percentage % this.details[i].DiscountNet = parseFloat( (this.detail.Unit_cost * this.details[i].discount) / 100 ); } if (this.details[i].tax_method == "1") { //Exclusive this.details[i].Net_cost = parseFloat( this.detail.Unit_cost - this.details[i].DiscountNet ); this.details[i].taxe = parseFloat( (this.detail.tax_percent * (this.detail.Unit_cost - this.details[i].DiscountNet)) / 100 ); } else { //Inclusive this.details[i].taxe = parseFloat( (this.detail.Unit_cost - this.details[i].DiscountNet) * (this.detail.tax_percent / 100) ); this.details[i].Net_cost = parseFloat( this.detail.Unit_cost - this.details[i].taxe - this.details[i].DiscountNet ); } this.$forceUpdate(); } } this.Calcul_Total(); this.$bvModal.hide("form_Update_Detail"); }, //------ Toast makeToast(variant, msg, title) { this.$root.$bvToast.toast(msg, { title: title, variant: variant, solid: true }); }, // Search Products search(){ if (this.timer) { clearTimeout(this.timer); this.timer = null; } if (this.search_input.length < 2) { return this.product_filter= []; } if (this.transfer.from_warehouse != "" && this.transfer.from_warehouse != null) { this.timer = setTimeout(() => { const product_filter = this.products.filter(product => product.code === this.search_input || product.barcode.includes(this.search_input)); if(product_filter.length === 1){ this.SearchProduct(product_filter[0]) }else{ this.product_filter= this.products.filter(product => { return ( product.name.toLowerCase().includes(this.search_input.toLowerCase()) || product.code.toLowerCase().includes(this.search_input.toLowerCase()) || product.barcode.toLowerCase().includes(this.search_input.toLowerCase()) ); }); // Check if product_filter is empty and show alert if (this.product_filter.length <= 0) { this.makeToast( "warning", "Product Not Found", "Warning" ); } } }, 800); } else { this.makeToast( "warning", this.$t("SelectWarehouse"), this.$t("Warning") ); } }, // get Result Value Search Product getResultValue(result) { return result.code + " " + "(" + result.name + ")"; }, // Submit Search Product SearchProduct(result) { this.product = {}; if ( this.details.length > 0 && this.details.some(detail => detail.code === result.code) ) { this.makeToast("warning", this.$t("AlreadyAdd"), this.$t("Warning")); } else { this.product.code = result.code; this.product.no_unit = 1; this.product.stock = result.qte_purchase; if (result.qte_purchase < 1) { this.product.quantity = result.qte_purchase; } else { this.product.quantity = 1; } this.product.product_variant_id = result.product_variant_id; this.Get_Product_Details(result.id, result.product_variant_id); } this.search_input= ''; this.$refs.product_autocomplete.value = ""; this.product_filter = []; }, //----------------------------------- verified Form ------------------------------\\ verifiedForm() { if (this.details.length <= 0) { this.makeToast( "warning", this.$t("AddProductToList"), this.$t("Warning") ); return false; } else if (this.transfer.from_warehouse === this.transfer.to_warehouse) { this.makeToast( "warning", this.$t("WarehouseIdentical"), this.$t("Warning") ); return false; } else { var count = 0; for (var i = 0; i < this.details.length; i++) { if (this.details[i].quantity == "") { count += 1; } } if (count > 0) { this.makeToast("warning", this.$t("AddQuantity"), this.$t("Warning")); return false; } else { return true; } } }, //-------------------------------- Update Transfer ----------------------\\ Update_Transfer() { if (this.verifiedForm()) { this.SubmitProcessing = true; // Start the progress bar. NProgress.start(); NProgress.set(0.1); let id = this.$route.params.id; axios .put(`transfers/${id}`, { transfer: this.transfer, details: this.details, GrandTotal: this.GrandTotal }) .then(response => { // Complete the animation of theprogress bar. NProgress.done(); this.SubmitProcessing = false; this.$router.push({ name: "index_transfer" }); this.makeToast( "success", this.$t("Successfully_Updated"), this.$t("Success") ); }) .catch(error => { // Complete the animation of theprogress bar. NProgress.done(); this.makeToast("danger", this.$t("InvalidData"), this.$t("Failed")); this.SubmitProcessing = false; }); } }, //-------------------------------- Get Last Detail Id -------------------------\\ Last_Detail_id() { this.product.detail_id = 0; var len = this.details.length; this.product.detail_id = this.details[len - 1].detail_id + 1; }, //----------------------------------------- Add product to order list -------------------------\\ add_product() { if (this.details.length > 0) { this.Last_Detail_id(); } else if (this.details.length === 0) { this.product.detail_id = 1; } this.details.push(this.product); }, //-----------------------------------Verified QTY ------------------------------\\ Verified_Qty(detail, id) { for (var i = 0; i < this.details.length; i++) { if (this.details[i].detail_id === id) { if (isNaN(detail.quantity)) { this.details[i].quantity = detail.qte_copy; } if (detail.etat == "new" && detail.quantity > detail.stock) { this.makeToast("warning", this.$t("LowStock"), this.$t("Warning")); this.details[i].quantity = detail.stock; } else if ( detail.etat == "current" && detail.quantity > detail.stock + detail.qte_copy ) { this.makeToast("warning", this.$t("LowStock"), this.$t("Warning")); this.details[i].quantity = detail.qte_copy; } else { this.details[i].quantity = detail.quantity; } } } this.$forceUpdate(); this.Calcul_Total(); }, //-----------------------------------increment QTY ------------------------------\\ increment(detail, id) { for (var i = 0; i < this.details.length; i++) { if (this.details[i].detail_id == id) { if (detail.etat == "new" && detail.quantity + 1 > detail.stock) { this.makeToast("warning", this.$t("LowStock"), this.$t("Warning")); } else if ( detail.etat == "current" && detail.quantity + 1 > detail.stock + detail.qte_copy ) { this.makeToast("warning", this.$t("LowStock"), this.$t("Warning")); } else { this.formatNumber(this.details[i].quantity++, 2); } } } this.$forceUpdate(); this.Calcul_Total(); }, //-----------------------------------decrement QTY ------------------------------\\ decrement(detail, id) { for (var i = 0; i < this.details.length; i++) { if (this.details[i].detail_id == id) { if (detail.quantity - 1 > 0) { if (detail.etat == "new" && detail.quantity - 1 > detail.stock) { this.makeToast( "warning", this.$t("LowStock"), this.$t("Warning") ); } else if ( detail.etat == "current" && detail.quantity - 1 > detail.stock + detail.qte_copy ) { this.makeToast( "warning", this.$t("LowStock"), this.$t("Warning") ); } else { this.formatNumber(this.details[i].quantity--, 2); } } } } this.$forceUpdate(); this.Calcul_Total(); }, //-----------------------------------------Calcul Total ------------------------------\\ Calcul_Total() { this.total = 0; for (let index = 0; index < this.details.length; index++) { var tax = this.details[index].taxe * this.details[index].quantity; this.details[index].subtotal = parseFloat( this.details[index].quantity * this.details[index].Net_cost + tax ); this.total = parseFloat(this.total + this.details[index].subtotal); } const total_without_discount = parseFloat( this.total - this.transfer.discount ); this.transfer.TaxNet = parseFloat( (total_without_discount * this.transfer.tax_rate) / 100 ); this.GrandTotal = parseFloat( total_without_discount + this.transfer.TaxNet + this.transfer.shipping ); var grand_total = this.GrandTotal.toFixed(2); this.GrandTotal = parseFloat(grand_total); }, //-----------------------------------Delete Detail Product ------------------------------\\ delete_Product_Detail(id) { for (var i = 0; i < this.details.length; i++) { if (id === this.details[i].detail_id) { this.details.splice(i, 1); this.Calcul_Total(); } } }, //---------- keyup OrderTax keyup_OrderTax() { if (isNaN(this.transfer.tax_rate)) { this.transfer.tax_rate = 0; } else if(this.transfer.tax_rate == ''){ this.transfer.tax_rate = 0; this.Calcul_Total(); }else { this.Calcul_Total(); } }, //---------- keyup Discount keyup_Discount() { if (isNaN(this.transfer.discount)) { this.transfer.discount = 0; } else if(this.transfer.discount == ''){ this.transfer.discount = 0; this.Calcul_Total(); }else { this.Calcul_Total(); } }, //---------- keyup Shipping keyup_Shipping() { if (isNaN(this.transfer.shipping)) { this.transfer.shipping = 0; } else if(this.transfer.shipping == ''){ this.transfer.shipping = 0; this.Calcul_Total(); }else { this.Calcul_Total(); } }, //------------------------------Formetted Numbers -------------------------\\ formatNumber(number, dec) { const value = (typeof number === "string" ? number : number.toString() ).split("."); if (dec <= 0) return value[0]; let formated = value[1] || ""; if (formated.length > dec) return `${value[0]}.${formated.substr(0, dec)}`; while (formated.length < dec) formated += "0"; return `${value[0]}.${formated}`; }, //------------------------------------ Get Products By Warehouse -------------------------\\ Get_Products_By_Warehouse(id) { // Start the progress bar. NProgress.start(); NProgress.set(0.1); axios .get("get_Products_by_warehouse/" + id + "?stock=" + 1 + "&product_service=" + 0 + "&product_combo=" + 1) .then(response => { this.products = response.data; NProgress.done(); }) .catch(error => { }); }, //---------------------------------Get Product Details ------------------------\\ Get_Product_Details(product_id, variant_id) { axios.get("/show_product_data/" + product_id +"/"+ variant_id).then(response => { this.product.discount = response.data.discount; this.product.DiscountNet = response.data.DiscountNet; this.product.discount_Method = response.data.discount_method; this.product.del = 0; this.product.id = 0; this.product.etat = "new"; this.product.product_id = response.data.id; this.product.name = response.data.name; this.product.Net_cost = response.data.Net_cost; this.product.Unit_cost = response.data.Unit_cost; this.product.taxe = response.data.tax_cost; this.product.tax_method = response.data.tax_method; this.product.tax_percent = response.data.tax_percent; this.product.unitPurchase = response.data.unitPurchase; this.product.purchase_unit_id = response.data.purchase_unit_id; this.add_product(); this.Calcul_Total(); }); }, //---------------------- Event Select From Warehouse ------------------------------\\ Selected_From_Warehouse(value) { this.search_input= ''; this.product_filter = []; this.Get_Products_By_Warehouse(value); }, //---------------------------------------Get Elements ------------------------------\\ GetElements() { let id = this.$route.params.id; axios .get(`transfers/${id}/edit`) .then(response => { this.transfer = response.data.transfer; this.details = response.data.details; this.warehouses = response.data.warehouses; this.to_warehouses = response.data.to_warehouses; this.Get_Products_By_Warehouse(this.transfer.from_warehouse); this.Calcul_Total(); this.isLoading = false; }) .catch(response => { setTimeout(() => { this.isLoading = false; }, 500); }); } }, //----------------------------- Created Function------------------- created: function() { this.GetElements(); } }; </script> <style> .input-with-icon { display: flex; align-items: center; } .scan-icon { width: 50px; /* Adjust size as needed */ height: 50px; margin-right: 8px; /* Adjust spacing as needed */ cursor: pointer; } </style>