Created
August 17, 2021 16:49
-
-
Save ghaffaru/5092ed16e535e2bfe2ad57aa7bc7e435 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <div> | |
| <div :class="$vuetify.theme.isDark ? 'bg-black' : 'bg-white'" v-if="!not_allowed" class="col-md-10 mx-auto col-sm-12 card"> | |
| <v-overlay | |
| :value="loading" | |
| :dark="false" | |
| > | |
| <v-progress-circular | |
| :size="50" | |
| color="green" | |
| indeterminate | |
| ></v-progress-circular> | |
| </v-overlay> | |
| <div class="card-header"> | |
| <v-row> | |
| <v-col cols="12" sm="2"> | |
| <v-btn text color="blue darken-4" to="/sales"><v-icon>mdi-arrow-left</v-icon> {{ $t("main.back") }}</v-btn> | |
| </v-col> | |
| <v-col cols="12" sm="10"> | |
| <h3 class="font-weight-light">{{ $t("quick_sale.create_new_sale") }}</h3> | |
| </v-col> | |
| </v-row> | |
| </div> | |
| <v-row> | |
| <v-col cols="12" sm="12" class="mx-auto"> | |
| <v-row> | |
| <v-col cols="12" sm="12" class="text-center"> | |
| <h1 class="font-weight-black">{{ $t("main.amount_due") }}: {{amount_due | toMoney | currency_symbol}}</h1> | |
| <h4 class="font-weight-light"> | |
| {{ $t("main.subtotal") }}: {{gross_amount | toMoney | currency_symbol}} | | |
| {{ $t("main.taxes") }}: {{tax_amount | toMoney | currency_symbol}} | | |
| {{ $t("main.discount") }}: ({{discount_amount | toMoney | currency_symbol}}) | |
| </h4> | |
| </v-col> | |
| </v-row> | |
| <v-row> | |
| <v-col cols="12" sm="3" class="text-right"> | |
| <v-switch color="success" :label="$t('main.print_receipt')" v-model="print_receipt"></v-switch> | |
| </v-col> | |
| <v-col cols="12" sm="3"> | |
| <v-menu | |
| v-model="startDate_menu" | |
| :close-on-content-click="false" | |
| :nudge-right="40" | |
| transition="scale-transition" | |
| offset-y | |
| min-width="290px" | |
| > | |
| <template v-slot:activator="{ on }"> | |
| <v-text-field | |
| v-model="entrydate" | |
| :label="$t('main.entry_date')" | |
| prepend-icon="event" | |
| readonly | |
| outlined="" | |
| v-on="on" | |
| ></v-text-field> | |
| </template> | |
| <v-date-picker v-model="entrydate" @input="startDate_menu = false"></v-date-picker> | |
| </v-menu> | |
| </v-col> | |
| <v-col cols="12" sm="4"> | |
| <account-dropdown | |
| :accountTypes="['Assets']" | |
| :subAccounts="payment_accounts" | |
| :label="$t('main.payment_account')" | |
| :hint="$t('main.payment_account_hint')" | |
| @accountChange="(id) => handleAccountChange(id, 'payment')" | |
| ></account-dropdown> | |
| </v-col> | |
| </v-row> | |
| <v-row> | |
| <v-col cols="12" sm="12" class="mx-auto text-center" > | |
| <h5 v-if="!sales_items.length>0" class="font-italic align-center">{{ $t("quick_sale.add_item") }}</h5> | |
| <v-form ref="item_form" class="mb-2"> | |
| <v-simple-table v-if="sales_items" class="table-hover"> | |
| <tbody> | |
| <tr v-for="(item, index) in sales_items" v-bind:key="index"> | |
| <td> | |
| <v-autocomplete | |
| :disabled="saving_progress" | |
| :items="items" | |
| item-value="id" | |
| item-text="name" | |
| :label="$t('main.item')" | |
| cache-items | |
| eager | |
| v-model="item.item" | |
| @change="apply_item(index)" | |
| return-object | |
| :no-data-text="$t('main.empty_product_service')" | |
| @focus="new_product= items.length===0" | |
| ></v-autocomplete> | |
| </td> | |
| <td> | |
| <v-textarea | |
| rows="2" | |
| small | |
| :label="$t('main.description')" | |
| v-model="item.description" | |
| auto-grow | |
| > | |
| </v-textarea> | |
| </td> | |
| <td> | |
| <v-text-field | |
| @keyup="compute_amount(item)" | |
| @change="item.rawUnit_price ? item.rawUnit_price=item.rawUnit_price : item.rawUnit_price =0; compute_amount(item)" | |
| type="number" | |
| :label="$t('main.price')" | |
| v-model="item.rawUnit_price" | |
| :prefix="$store.state.user.user_infor.current_business.currency.symbol" | |
| > | |
| </v-text-field> | |
| </td> | |
| <td> | |
| <v-text-field | |
| @keyup="compute_amount(item)" | |
| @change="item.invoice_quantity ? item.invoice_quantity=item.invoice_quantity : item.invoice_quantity=1; compute_amount(item)" | |
| type="number" | |
| :label="$t('main.quantity')" | |
| v-model="item.invoice_quantity" | |
| :rules="required_rules" | |
| > | |
| </v-text-field> | |
| </td> | |
| <td class="text-center"> | |
| {{item.invoice_amount | toMoney}} <br> {{ $t("main.amount") }} | |
| </td> | |
| <td> | |
| <v-select | |
| :items="item.taxes" | |
| item-value="id" | |
| item-text="display_name" | |
| v-model="item.tax_id" | |
| clearable | |
| @change="compute_amount(item)" | |
| :hint="item.tax_amount | toMoney |currency_symbol" | |
| persistent-hint | |
| :label="$t('main.tax')" | |
| > | |
| </v-select> | |
| </td> | |
| <td> | |
| <v-row> | |
| <v-col cols="12" sm="12" class="p-0"> | |
| <v-btn class="text-muted" @click="moveItem_up(index,item)" v-if="index != 0 " icon small><v-icon>mdi-arrow-up</v-icon></v-btn> | |
| </v-col> | |
| <v-col cols="12" sm="12" class="p-0"> | |
| <v-btn @click="remove_item(index)" color="red" icon small><v-icon>mdi-close</v-icon></v-btn> | |
| </v-col> | |
| <v-col cols="12" sm="12" class="p-0"> | |
| <v-btn @click="moveItem_down(index,item)" class="text-muted" v-if="index < (sales_items.length-1)" icon small><v-icon>mdi-arrow-down</v-icon></v-btn> | |
| </v-col> | |
| </v-row> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </v-simple-table> | |
| </v-form> | |
| <v-btn :disabled="quantity_error" rounded x-large outlined color="green" @click="add_line" >{{ sales_items.length>0 ? 'Add another item' : 'Add item' }}</v-btn> | |
| <v-btn | |
| small | |
| :disabled="quantity_error" | |
| rounded | |
| x-large | |
| outlined | |
| color="green" | |
| text | |
| dark | |
| @click="$store.state.new_item = true; retailbyDefaule=true;" | |
| ><v-icon>mdi-plus</v-icon> {{ $t("main.new_item") }}</v-btn> | |
| </v-col> | |
| <tag-input | |
| :message="$t('tags.sale_tag')" | |
| color="green" | |
| @tags="setTags" | |
| :tagFill="tagFill" | |
| > | |
| </tag-input> | |
| </v-row> | |
| <v-row class="mb-2"> | |
| <v-col cols="12" sm="10" class="mx-auto" v-if="sales_items.length"> | |
| <v-textarea | |
| outlined | |
| :label="$t('main.note')" | |
| v-model="note" | |
| rows="2" | |
| auto-grow | |
| > | |
| </v-textarea> | |
| </v-col> | |
| </v-row> | |
| </v-col> | |
| </v-row> | |
| <div class="card-footer"> | |
| <v-row> | |
| <v-spacer></v-spacer> | |
| <v-col cols="12" sm="6"> | |
| <v-menu | |
| v-model="discount_dlg" | |
| :close-on-content-click="false" | |
| :nudge-width="200" | |
| offset-x | |
| ref="discount_menu" | |
| > | |
| <template v-slot:activator="{ on }"> | |
| <v-btn | |
| x-large | |
| outlined | |
| color="green" | |
| dark | |
| rounded | |
| v-on="on" | |
| > | |
| {{ $t("main.add_discount") }} | |
| </v-btn> | |
| </template> | |
| <v-card | |
| style="max-width: 400px" | |
| class="p-1" | |
| > | |
| <v-list> | |
| <v-list-item> | |
| <v-list-item-title> {{ $t("main.apply_discount") }}</v-list-item-title> | |
| </v-list-item> | |
| <v-list-item> | |
| <v-list-item-action> | |
| <v-switch :label="$t('main.enter_amount')" @change="discount_percentageSwitch = ! discount_percentageSwitch" v-model="discount_amountSwitch" color="blue darken-4"></v-switch> | |
| </v-list-item-action> | |
| <v-list-item-title> | |
| <v-text-field | |
| class="m-2" | |
| outlined | |
| @keyup="compute_total_amount" | |
| v-model="discount_amount" | |
| :disabled="!discount_amountSwitch" | |
| :placeholder="$t('main.amount')" | |
| ></v-text-field> | |
| </v-list-item-title> | |
| </v-list-item> | |
| <v-list-item > | |
| <v-list-item-action> | |
| <v-switch label=" %" @change="discount_amountSwitch = !discount_amountSwitch" v-model="discount_percentageSwitch" color="purple"></v-switch> | |
| </v-list-item-action> | |
| <v-list-item-title> | |
| <v-text-field | |
| class="m-2" | |
| outlined | |
| @keyup="compute_discountPercentage" | |
| v-model="discount_percentage" | |
| :disabled="!discount_percentageSwitch" | |
| @change="compute_discountPercentage" | |
| placeholder="%" | |
| ></v-text-field> | |
| </v-list-item-title> | |
| </v-list-item> | |
| <v-list-item> | |
| <v-btn @click="$refs.discount_menu.isActive =false;" small text color="success"> {{ $t("main.done") }}</v-btn> | |
| </v-list-item> | |
| </v-list> | |
| </v-card> | |
| </v-menu> | |
| <span v-if="discount_percentageSwitch" style="font-size: 18px;" class="font-weight-light ">{{discount_percentage}}%: {{discount_amount | toMoney | currency_symbol}} </span> | |
| <span v-if="discount_amountSwitch" style="font-size: 18px;" class="font-weight-light ">{{ discount_amount | toMoney | currency_symbol}} </span> | |
| </v-col> | |
| <v-col | |
| cols="12" | |
| sm="2" | |
| > | |
| <v-btn :disabled="quantity_error" :loading="saving_progress" @click="save_cart" rounded color="success" x-large>{{ $t("main.save") }}</v-btn> | |
| </v-col> | |
| </v-row> | |
| </div> | |
| </div> | |
| <cannotview-component v-else></cannotview-component> | |
| <new-item-component | |
| @ItemCreated="create_item" | |
| :selling_default="retailbyDefaule" | |
| > | |
| </new-item-component> | |
| <v-snackbar | |
| v-model="success_message" | |
| :timeout="snack_timeout" | |
| > | |
| {{toast_msg}} | |
| <v-btn | |
| color="success" | |
| text | |
| @click="success_message = false" | |
| > | |
| {{ $t("main.cancel") }} | |
| </v-btn> | |
| </v-snackbar> | |
| <v-snackbar | |
| v-model="error_message" | |
| color="error" | |
| :timeout="snack_timeout" | |
| > | |
| {{error_msg}} | |
| <v-btn | |
| color="light" | |
| text | |
| @click="error_message = false" | |
| > | |
| {{ $t("main.close") }} | |
| </v-btn> | |
| </v-snackbar> | |
| </div> | |
| </template> | |
| <script> | |
| import moment from "moment"; | |
| import CannotviewComponent from "./cannotviewComponent"; | |
| import NewItemComponent from "../product/NewItemComponent"; | |
| const AccountDropdown = ()=>import('./accountDropdown.vue'); | |
| const loginComponent = ()=>import('./loginComponent'); | |
| const tagInput = () => import("./tagInput") | |
| export default { | |
| name: "newsaleComponent", | |
| components:{ | |
| NewItemComponent, | |
| CannotviewComponent, | |
| tagInput, | |
| AccountDropdown | |
| }, | |
| data(){ | |
| return{ | |
| retailbyDefaule:false, | |
| tags: [], | |
| tagFill: false, | |
| categories:[], | |
| cat_loading:false, | |
| category_id:null, | |
| img_preview:'/img/item_photo.png', | |
| has_photo:false, | |
| change_photo:false, | |
| not_allowed:false, | |
| print_receipt:true, | |
| selling_price:0, | |
| display_unitPrice:0, | |
| code:'', | |
| quantity_error:false, | |
| unit_price:0, | |
| name:'', | |
| formValid:false, | |
| saving_progress:false, | |
| is_product:true, | |
| new_product:false, | |
| search_value:'', | |
| payment_accounts:[], | |
| payment_account:null, | |
| delete_dialog:false, | |
| sale_id:'', | |
| gross_amount:0, | |
| amount_due:0, | |
| snack_timeout:4500, | |
| snack_infinite:0, | |
| search:'', | |
| business_name:'', | |
| business_logo:'', | |
| business_address:'', | |
| business_phone:'', | |
| business_email:'', | |
| loading:false, | |
| success_message:false, | |
| sales_preview:false, | |
| toast_msg:'', | |
| items:[], | |
| items_alt:[], | |
| sales:[], | |
| error_msg:'', | |
| error_message:false, | |
| client_error:false, | |
| editing:false, | |
| create_overlay:false, | |
| discount_percentage:0, | |
| discount_percentageSwitch:true, | |
| discount_amountSwitch:false, | |
| discount_amount:0, | |
| discounted_amount:0, | |
| note:'', | |
| sale_number:'', | |
| discount_dlg:false, | |
| sales_items:[], | |
| sales_dialog:false, | |
| startDate_menu:false, | |
| entrydate:'', | |
| clear_dialog:false, | |
| item_type:'Product', | |
| item_types:[{text:'Product',value:'Product'},{text:'Service',value:'Service'}], | |
| buy:false, | |
| tax_amount:0, | |
| retail:true, | |
| taxed:false, | |
| sales_accounts:[], | |
| sales_account:null, | |
| purchase_accounts:[], | |
| purchase_account:null, | |
| track_inventory:false, | |
| description:'', | |
| alltaxes:[], | |
| item_tax:null, | |
| nameRules: [ | |
| v => !!v || this.$t("main.item_name_required"), | |
| //v => (v && v.length <= 10) || 'Name must be less than 10 characters', | |
| ], | |
| required_rules:[ | |
| v => !!v || this.$t("main.required"), | |
| v => v>0 || this.$t("main.invalid_value"), | |
| ], | |
| headers: [ | |
| { | |
| text: 'SALE #', | |
| align: 'center', | |
| sortable: true, | |
| value: 'sales_number', | |
| }, | |
| { text: 'NET AMOUNT', value: 'amount_due' }, | |
| { text: 'ENTRY DATE', value: 'entry_date', | |
| align:'center', | |
| }, | |
| { text: 'CREATED ON', value: 'created_at' }, | |
| { text: 'ACTIONS', value: 'id', align:'center' }, | |
| ] | |
| } | |
| }, | |
| computed: { | |
| baseUrl() { | |
| return this.$store.state.baseURL | |
| }, | |
| businessCurrency(){ | |
| return this.$store.state.user.user_infor.current_business.currency; | |
| } | |
| }, | |
| methods:{ | |
| setTags(tags) { | |
| this.tags = tags | |
| }, | |
| handleAccountChange(accountId, type) { | |
| if (type === "payment") this.payment_account = accountId | |
| if (type === "sales") this.sales_account = accountId | |
| if (type === "purchase") this.purchase_account = accountId | |
| }, | |
| get_categories(){ | |
| this.cat_loading=true; | |
| axios.get('/api/itemcategories') | |
| .then(res=>{ | |
| this.categories = res.data; | |
| this.category_id = this.categories[0].id; | |
| this.cat_loading=false; | |
| }) | |
| }, | |
| remove_photo(){ | |
| this.photo=null; | |
| this.img_preview='/img/item_photo.png'; | |
| this.has_photo=false; | |
| this.change_photo=true; | |
| }, | |
| select_image(){ | |
| let image_selector = document.getElementById('item_photo'); | |
| image_selector.click(); | |
| }, | |
| set_image(e){ | |
| this.photo = e.target.files[0]; | |
| const fr = new FileReader(); | |
| fr.readAsDataURL(this.photo); | |
| fr.onload = ()=>{ | |
| this.img_preview = fr.result; | |
| this.has_photo=true; | |
| } | |
| }, | |
| get_default_account(accounts,account_name=null){ | |
| return accounts.filter(account=>{ | |
| return account.account_name == account_name; | |
| }); | |
| }, | |
| apply_item(i){ | |
| let item = this.sales_items[i]; | |
| if(item.track_inventory === 1 && Number(item.display_unitPrice) ===0){ | |
| this.error_msg = this.$t("item.stock_error"); | |
| this.error_message =true; | |
| } | |
| let product= JSON.parse(JSON.stringify(item.item)); | |
| product.invoice_quantity =1; | |
| this.sales_items[i] = product ; | |
| this.sales_items[i].item = product; | |
| //item = product ; | |
| this.compute_amount(this.sales_items[i]); | |
| //this.compute_total_amount(); | |
| this.compute_discountPercentage(); | |
| }, | |
| get_country_and_taxes(){ | |
| axios.get('/api/getcountryinfo') | |
| .then(res=>{ | |
| this.$store.state.user.countryInfo = res.data; | |
| this.alltaxes = res.data.usertaxes; | |
| this.loading = false; | |
| }) | |
| .catch(()=>{ | |
| this.error_msg = this.$t("quick_sale.sales_account_error"); | |
| this.error_message = true; | |
| this.sales_dialog = false; | |
| this.loading = false; | |
| }); | |
| }, | |
| type_change(){ | |
| this.is_product = this.item_type=='Product' ? true:false; | |
| }, | |
| create_item(item){ | |
| this.add_item(item); | |
| this.items.push(item); | |
| this.retailbyDefaule = false; | |
| }, | |
| search_item(){ | |
| let new_list = []; | |
| new_list = new_list.length > 0 ? new_list : JSON.parse(JSON.stringify(this.items)); | |
| let search_match = []; | |
| if(this.search_value.length >0){ | |
| for(let i =0; i<new_list.length;i++){ | |
| if(new_list[i].name.toLowerCase().indexOf(this.search_value.toLowerCase())> -1){ | |
| search_match.push(new_list[i]); | |
| } | |
| } | |
| this.items = search_match; | |
| }else{ | |
| this.items = JSON.parse(JSON.stringify(this.items_alt)); | |
| } | |
| }, | |
| print_invoice(){ | |
| window.print(); | |
| }, | |
| view_details(item){ | |
| this.$store.state.selected_invoice = item; | |
| this.sales_preview = true; | |
| }, | |
| new_sale(){ | |
| this.editing = false; | |
| this.sales_dialog = true; | |
| this.sale_number =''; | |
| this.get_items(); | |
| }, | |
| compute_discountPercentage(){ | |
| if(this.discount_percentageSwitch){ | |
| this.discount_amount = this.gross_amount*(this.discount_percentage/100); | |
| this.amount_due =this.gross_amount - this.discount_amount; | |
| this.amount_due+=Number(this.tax_amount); | |
| } | |
| }, | |
| compute_inputTax(rate,amount){ | |
| return (Number(rate)/100)*Number(amount); | |
| }, | |
| compute_total_amount(){ | |
| let gross_amount = 0; | |
| let tax_amount = 0; | |
| this.quantity_error=false; | |
| this.sales_items.forEach(item=>{ | |
| if(item.track_inventory==1){ | |
| if(item.invoice_quantity > item.quantity){ | |
| this.quantity_error = true; | |
| this.error_msg = "Invalid quantity provided for "+item.name+", you have "+item.quantity+" of "+item.name+" in stock"; | |
| this.error_message =true; | |
| }else{ | |
| this.quantity_error = false; | |
| this.error_message =false; | |
| } | |
| }else{ | |
| this.quantity_error = false; | |
| } | |
| let total_tax = 0; | |
| if(item.tax_id){ | |
| let selected_tax = item.taxes.find(tax=>{ | |
| return tax.id == item.tax_id; | |
| }); | |
| if(selected_tax.type=='Flat'){ | |
| item.tax_amount = this.compute_inputTax(selected_tax.rate,item.invoice_amount); | |
| tax_amount += item.tax_amount; | |
| gross_amount += item.invoice_amount; | |
| }else if(selected_tax.type=='Compound'){ | |
| //compute input taxes before applying compound taxes | |
| let subamount = this.compute_inputTax(selected_tax.sub_rate,item.invoice_amount); | |
| let compound_amount = Number(subamount) + Number(item.invoice_amount); | |
| let compound_taxAmount = this.compute_inputTax(selected_tax.rate,compound_amount); | |
| item.tax_amount = compound_taxAmount+subamount; | |
| item.total_tax_rate = total_tax; | |
| // gross_amount+= Number(item.tax_amount)+Number(item.invoice_amount)+Number(subamount); | |
| // item.tax_amount+=subamount; | |
| tax_amount += item.tax_amount; | |
| gross_amount += item.invoice_amount; | |
| } | |
| }else{ | |
| item.tax_amount=0; | |
| item.total_tax_rate = 0; | |
| gross_amount+=Number(item.invoice_amount); | |
| } | |
| }); | |
| this.tax_amount = tax_amount; | |
| this.compute_discountPercentage(); | |
| this.gross_amount = gross_amount; | |
| this.amount_due = (Number(gross_amount) - Number(this.discount_amount)) +this.tax_amount; | |
| }, | |
| remove_item(index){ | |
| this.sales_items.splice(index,1); | |
| this.compute_total_amount(); | |
| this.compute_discountPercentage(); | |
| }, | |
| compute_amount(item){ | |
| if(item.invoice_quantity){ | |
| item.invoice_amount = (Number(item.rawUnit_price) * Number(item.invoice_quantity)); | |
| } | |
| this.compute_total_amount(); | |
| }, | |
| delete_item(item){ | |
| this.sale_number = item.sales_number; | |
| this.sale_id = item.id; | |
| this.delete_dialog = true; | |
| }, | |
| get_items(){ | |
| this.loading = true; | |
| axios.get("/api/getinvoiceitems") | |
| .then(res=>{ | |
| this.items=res.data; | |
| this.items_alt=res.data; | |
| this.loading=false; | |
| if(this.$route.query.item_id){ | |
| let searchItem = this.items.find(item=>{ return item.id==this.$route.query.item_id}); | |
| if (searchItem){ | |
| this.create_item(searchItem); | |
| } | |
| } | |
| this.get_country_and_taxes(); | |
| }) | |
| .catch(()=>{ | |
| this.error_msg=this.$t("main.error_msg"); | |
| this.error_message=true; | |
| }); | |
| }, | |
| reload_items(){ | |
| this.loading = true; | |
| axios.get("/api/getinvoiceitems") | |
| .then(res=>{ | |
| this.items=res.data; | |
| this.items_alt=res.data; | |
| this.loading=false; | |
| }) | |
| .catch(()=>{ | |
| this.error_msg=this.$t("main.error_msg"); | |
| this.error_message=true; | |
| }); | |
| }, | |
| get_salenumber(){ | |
| axios.get('/api/getsalenumber') | |
| .then(number=>{ | |
| this.sale_number = number.data; | |
| this.loading=false; | |
| }) | |
| .catch(()=>{ | |
| this.sales_dialog=false; | |
| this.error_msg=this.$t("main.error_msg"); | |
| this.error_message=true; | |
| }); | |
| }, | |
| prep_items(items){ | |
| let new_items=[]; | |
| items.forEach(item=>{ | |
| item.item=null; | |
| new_items.push(item); | |
| }); | |
| return new_items; | |
| }, | |
| reprep_items(){ | |
| this.sales_items.forEach(item=>{ | |
| item.item=item; | |
| }); | |
| }, | |
| save_cart(){ | |
| if (this.quantity_error){ | |
| this.error_message=true; | |
| return false; | |
| } | |
| if (!this.validate_items()){ | |
| return false; | |
| } | |
| if(this.sales_items.length){ | |
| if(!this.payment_account){ | |
| this.error_msg=this.$t("main.payment_account_selected_error"); | |
| this.error_message=true; | |
| return false; | |
| } | |
| if(this.$refs.item_form.validate()){ | |
| this.saving_progress=true; | |
| let cart={ | |
| entry_date:this.entrydate, | |
| sale_number:this.sale_number, | |
| gross_amount:this.gross_amount, | |
| discount_amount:this.discount_amount, | |
| amount_due:this.amount_due, | |
| items:this.prep_items(this.sales_items), | |
| note:this.note, | |
| tag: this.tags.toString(), | |
| payment_accountID:this.payment_account | |
| }; | |
| axios.post('/api/savesale',cart) | |
| .then(sale=>{ | |
| this.saving_progress=false; | |
| this.toast_msg=this.$t("quick_sale.sale_create_success"); | |
| this.success_message=true; | |
| this.sales_items = []; | |
| this.discount_amount=0; | |
| this.discount_percentage=0; | |
| this.tax_amount=0; | |
| this.amount_due=0; | |
| this.gross_amount=0; | |
| this.tags = [] | |
| this.tagFill = true | |
| if (this.print_receipt){ | |
| let w = window.open(this.baseUrl + '/printposreceipt/'+sale.data.enc_id,"Sales receipt"+sale.data.sales_number, 'height=800,width=900'); | |
| w.onload=function (e) { | |
| w.print(); | |
| }; | |
| } | |
| this.reload_items(); | |
| }) | |
| .catch(err=>{ | |
| this.saving_progress=false; | |
| this.error_msg= err.response.status===302 ? err.response.data : this.$t("quick_sale.item_create_error"); | |
| this.error_message=true; | |
| this.reprep_items(); | |
| }); | |
| } | |
| }else{ | |
| this.error_msg=this.$t("quick_sale.cart_empty_error"); | |
| this.error_message=true; | |
| } | |
| }, | |
| // add_item(item){ | |
| // if(item.track_inventory === 1 && Number(item.display_unitPrice) ==0){ | |
| // this.error_msg = "This item is out of stocked, please purchase this item before you can sell it"; | |
| // this.error_message =true; | |
| // return false; | |
| // } | |
| // let newitem =JSON.parse(JSON.stringify(item)); | |
| // newitem.invoice_quantity=1; | |
| // this.sales_items.push(newitem); | |
| // | |
| // this.compute_total_amount(); | |
| // this.compute_discountPercentage(); | |
| // | |
| // this.$refs.item_menu.isActive = false; | |
| // | |
| // }, | |
| validate_items(){ | |
| let res = true; | |
| for (let item of this.sales_items){ | |
| if (!item.id){ | |
| this.error_msg=this.$t("item.item_line_error"); | |
| this.error_message=true; | |
| res = false; | |
| break; | |
| } | |
| } | |
| return res; | |
| }, | |
| add_line(){ | |
| let item = { | |
| id:null, | |
| description:'', | |
| tax_id:'' , | |
| rawUnit_price:0, | |
| invoice_amount:0, | |
| invoice_quantity:1, | |
| item:{} | |
| }; | |
| this.sales_items.push(item); | |
| }, | |
| add_item(item){ | |
| if(item.track_inventory == 1 && Number(item.display_unitPrice) ==0){ | |
| this.error_msg = this.$t("item.stock_error") | |
| this.error_message =true; | |
| return false; | |
| } | |
| let newitem =JSON.parse(JSON.stringify(item)); | |
| this.items.push(newitem); | |
| newitem.item = JSON.parse(JSON.stringify(item)); | |
| newitem.invoice_quantity=1; | |
| this.sales_items.push(newitem); | |
| this.compute_total_amount(); | |
| this.compute_discountPercentage(); | |
| }, | |
| moveItem_up(index,item){ | |
| let index2 = index-1; | |
| let item2 = this.sales_items[index2]; | |
| this.sales_items[index]=item2; | |
| this.sales_items[index2]=item; | |
| this.sales_items.push({}); | |
| let lastindex = (this.sales_items.length -1); | |
| this.remove_item(lastindex); | |
| }, | |
| moveItem_down(index,item){ | |
| let index2 = index+1; | |
| let item2 = this.sales_items[index2]; | |
| this.sales_items[index]=item2; | |
| this.sales_items[index2]=item; | |
| this.sales_items.push({}); | |
| let lastindex = (this.sales_items.length -1); | |
| this.remove_item(lastindex); | |
| } | |
| }, | |
| mounted() { | |
| if (this.$store.state.user.user_infor.is_admin==1){ | |
| this.not_allowed=false; | |
| this.get_items(); | |
| }else { | |
| if(this.$store.state.user.user_infor.components[2].roles.create == 1){ | |
| this.not_allowed=false; | |
| this.get_items(); | |
| }else { | |
| this.not_allowed=true; | |
| this.progress = false; | |
| return false; | |
| } | |
| } | |
| let sales_sub = this.$store.state.user.countryInfo.incomeAccounts.subtypes.filter(account_type=>{ | |
| return account_type.name == "Revenue"; | |
| }); | |
| this.sales_accounts = sales_sub[0].accounts; | |
| this.sales_account = this.sales_accounts[1].id; | |
| let expense_sub = this.$store.state.user.countryInfo.expenseAccounts.subtypes.filter(account_type=>{ | |
| return account_type.name == "Cost of Sale"; | |
| }); | |
| let expense_sub2 = this.$store.state.user.countryInfo.expenseAccounts.subtypes.filter(account_type=>{ | |
| return account_type.name == "Operating Expenses"; | |
| }); | |
| this.purchase_accounts = [...expense_sub[0].accounts, ...expense_sub2[0].accounts]; | |
| // let default_account = this.get_default_account(expense_sub[0].accounts,'Purchases'); | |
| // let default_sales = this.get_default_account(sales_sub[0].accounts,'Sales Revenue'); | |
| // // this.sales_account=default_sales[0].id; | |
| // this.purchase_account = default_account[0].id; | |
| this.entrydate = moment().format('Y-M-D'); | |
| let sales2_sub = this.$store.state.user.countryInfo.assetAccounts.subtypes.filter(account_type=>{ | |
| return account_type.name == "Cash & Bank"; | |
| }); | |
| let all_payment_accounts = sales2_sub[0].accounts; | |
| this.payment_accounts = all_payment_accounts.filter(account=>{ | |
| return !account.currency || account.currency === this.businessCurrency.code; | |
| }); | |
| } | |
| } | |
| </script> | |
| <style scoped> | |
| .v-menu__content{ | |
| max-height: 100%; | |
| overflow-y: auto !important; | |
| } | |
| @media screen and (max-device-width:768px) { | |
| td { | |
| display: table-row; | |
| width: 100% !important; | |
| } | |
| td> .v-input{ | |
| min-width: 360px !important; | |
| align-self: center; | |
| } | |
| } | |
| @media screen and (device-width:768px) { | |
| td { | |
| display: table-row; | |
| width: 100% !important; | |
| } | |
| td> .v-input{ | |
| min-width: 660px !important; | |
| align-self: center; | |
| } | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment