Merge Invoice and Bill into Document
This commit is contained in:
		
							
								
								
									
										242
									
								
								resources/assets/js/components/AkauntingCompanyEdit.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								resources/assets/js/components/AkauntingCompanyEdit.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="document-add-info-content-info-business fs-exclude">
 | 
			
		||||
        <div class="table-responsive">
 | 
			
		||||
            <table class="table table-borderless p-0">
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th class="text-right p-0">
 | 
			
		||||
                            <strong class="text-strong">{{ company.name }}</strong>
 | 
			
		||||
                        </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr v-if="company.address">
 | 
			
		||||
                        <th class="text-right p-0">
 | 
			
		||||
                            {{ company.address }}
 | 
			
		||||
                        </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr v-if="company.tax_number">
 | 
			
		||||
                        <th class="text-right p-0">
 | 
			
		||||
                            {{ 'general.tax_number' }}: {{ company.tax_number }}
 | 
			
		||||
                        </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr v-if="company.phone">
 | 
			
		||||
                        <th class="text-right p-0">
 | 
			
		||||
                            {{ company.phone }}
 | 
			
		||||
                        </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th class="text-right p-0">
 | 
			
		||||
                            {{ company.email }}
 | 
			
		||||
                        </th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <button type="button" class="btn btn-link text-right" @click="onEditCompany">{{ buttonText }}</button>
 | 
			
		||||
 | 
			
		||||
        <component v-bind:is="company_html" @submit="onSubmit" @cancel="onCancel"></component>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import { Select, Option, OptionGroup, ColorPicker } from 'element-ui';
 | 
			
		||||
 | 
			
		||||
import AkauntingModalAddNew from './AkauntingModalAddNew';
 | 
			
		||||
import AkauntingModal from './AkauntingModal';
 | 
			
		||||
import AkauntingMoney from './AkauntingMoney';
 | 
			
		||||
import AkauntingRadioGroup from './forms/AkauntingRadioGroup';
 | 
			
		||||
import AkauntingSelect from './AkauntingSelect';
 | 
			
		||||
import AkauntingDate from './AkauntingDate';
 | 
			
		||||
 | 
			
		||||
import Form from './../plugins/form';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'akaunting-company-edit',
 | 
			
		||||
 | 
			
		||||
    components: {
 | 
			
		||||
        [Select.name]: Select,
 | 
			
		||||
        [Option.name]: Option,
 | 
			
		||||
        [OptionGroup.name]: OptionGroup,
 | 
			
		||||
        [ColorPicker.name]: ColorPicker,
 | 
			
		||||
        AkauntingModalAddNew,
 | 
			
		||||
        AkauntingModal,
 | 
			
		||||
        AkauntingMoney,
 | 
			
		||||
        AkauntingRadioGroup,
 | 
			
		||||
        AkauntingSelect,
 | 
			
		||||
        AkauntingDate,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
  props: {
 | 
			
		||||
    buttonText: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'Edit your business address ',
 | 
			
		||||
      description: 'Input placeholder'
 | 
			
		||||
    },
 | 
			
		||||
    taxNumberTax: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'Tax Number',
 | 
			
		||||
      description: 'Input placeholder'
 | 
			
		||||
    }, 
 | 
			
		||||
    companyId: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '',
 | 
			
		||||
      description: 'Contact search route'
 | 
			
		||||
    },
 | 
			
		||||
    company: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: {},
 | 
			
		||||
      description: 'Company object'
 | 
			
		||||
    },
 | 
			
		||||
    companyForm: {
 | 
			
		||||
        type: Object,
 | 
			
		||||
        default: function () {
 | 
			
		||||
            return {
 | 
			
		||||
                text: 'Add New Item',
 | 
			
		||||
                show: false,
 | 
			
		||||
                buttons: {}
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        description: "Selectbox Add New Item Feature"
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      form: {},
 | 
			
		||||
      company_form: {
 | 
			
		||||
          text: this.companyForm.text,
 | 
			
		||||
          show: false,
 | 
			
		||||
          path: url + '/modals/companies/' + this.companyId + '/edit',
 | 
			
		||||
          buttons: this.companyForm.buttons,
 | 
			
		||||
      },
 | 
			
		||||
      company_html: '',
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    // Edit Company information
 | 
			
		||||
    onEditCompany() {
 | 
			
		||||
        let company_form = this.company_form;
 | 
			
		||||
 | 
			
		||||
        window.axios.get(company_form.path)
 | 
			
		||||
        .then(response => {
 | 
			
		||||
            company_form.show = true;
 | 
			
		||||
            company_form.html = response.data.html;
 | 
			
		||||
 | 
			
		||||
            this.company_html = Vue.component('add-new-component', function (resolve, reject) {
 | 
			
		||||
                resolve({
 | 
			
		||||
                    template: '<div><akaunting-modal-add-new :show="company_form.show" @submit="onSubmit" @cancel="onCancel" :buttons="company_form.buttons" :title="company_form.text" :is_component=true :message="company_form.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                    components: {
 | 
			
		||||
                        AkauntingModalAddNew,
 | 
			
		||||
                    },
 | 
			
		||||
 | 
			
		||||
                    data: function () {
 | 
			
		||||
                        return {
 | 
			
		||||
                            company_form: company_form,
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
 | 
			
		||||
                    methods: {
 | 
			
		||||
                      onSubmit(event) {
 | 
			
		||||
                          this.$emit('submit', event);
 | 
			
		||||
                      },
 | 
			
		||||
 | 
			
		||||
                      onCancel(event) {
 | 
			
		||||
                          this.$emit('cancel', event);
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }, this);
 | 
			
		||||
        })
 | 
			
		||||
        .catch(e => {
 | 
			
		||||
            console.log(e);
 | 
			
		||||
        })
 | 
			
		||||
        .finally(function () {
 | 
			
		||||
            // always executed
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onSubmit(event) {
 | 
			
		||||
        this.form = event;
 | 
			
		||||
 | 
			
		||||
        this.loading = true;
 | 
			
		||||
 | 
			
		||||
        let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
        FormData.prototype.appendRecursive = function(data, wrapper = null) {
 | 
			
		||||
            for(var name in data) {
 | 
			
		||||
                if (wrapper) {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], name);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(name, data[name]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let form_data = new FormData();
 | 
			
		||||
        form_data.appendRecursive(data);
 | 
			
		||||
 | 
			
		||||
        window.axios({
 | 
			
		||||
            method: this.form.method,
 | 
			
		||||
            url: this.form.action,
 | 
			
		||||
            data: form_data,
 | 
			
		||||
            headers: {
 | 
			
		||||
                'X-CSRF-TOKEN': window.Laravel.csrfToken,
 | 
			
		||||
                'X-Requested-With': 'XMLHttpRequest',
 | 
			
		||||
                'Content-Type': 'multipart/form-data'
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .then(response => {
 | 
			
		||||
            this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
            if (response.data.success) {
 | 
			
		||||
                let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
                this.company.name = data.name;
 | 
			
		||||
                this.company.email = data.email;
 | 
			
		||||
                this.company.tax_number = data.tax_number;
 | 
			
		||||
                this.company.phone = data.phone;
 | 
			
		||||
                this.company.address = data.address;
 | 
			
		||||
 | 
			
		||||
                this.company_form.show = false;
 | 
			
		||||
 | 
			
		||||
                this.company_form.html = '';
 | 
			
		||||
                this.company_html = null;
 | 
			
		||||
 | 
			
		||||
                this.$emit('changed', data);
 | 
			
		||||
 | 
			
		||||
                let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
                documentClasses.remove("modal-open");
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
            this.form.loading = false;
 | 
			
		||||
            console.log(error);
 | 
			
		||||
            this.company_html = error.message;
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onCancel() {
 | 
			
		||||
        this.company_form.show = false;
 | 
			
		||||
        this.company_form.html = null;
 | 
			
		||||
        this.company_html = null;
 | 
			
		||||
 | 
			
		||||
        let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
        documentClasses.remove("modal-open");
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										587
									
								
								resources/assets/js/components/AkauntingContactCard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										587
									
								
								resources/assets/js/components/AkauntingContactCard.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,587 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div :id="'select-contact-card-' + _uid" class="form-group col-md-12 invoice-add__body__top-form__customer">
 | 
			
		||||
        <div class="invoice-customer" :class="[{'fs-exclude': show.contact_selected}]">
 | 
			
		||||
            <div class="document-contact-without-contact">
 | 
			
		||||
                <div v-if="!show.contact_selected" class="document-contact-without-contact-box__customer-select fs-exclude">
 | 
			
		||||
                    <div class="aka-select aka-select--medium is-open" tabindex="0">
 | 
			
		||||
                        <div>
 | 
			
		||||
                            <div class="aka-box aka-box--large">
 | 
			
		||||
                                <div class="aka-box__content">
 | 
			
		||||
                                    <div class="document-contact-without-contact-box">
 | 
			
		||||
                                        <button type="button" class="btn-aka-link aka-btn--fluid document-contact-without-contact-box-btn"
 | 
			
		||||
                                        @click="onContactList">
 | 
			
		||||
                                            <i class="far fa-user fa-2x"></i> Add a customer
 | 
			
		||||
                                        </button>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        
 | 
			
		||||
                        <div class="aka-select-menu" v-if="show.contact_list">
 | 
			
		||||
                            <div class="aka-select-search-container">
 | 
			
		||||
                                <span class="aka-prefixed-input aka-prefixed-input--fluid">
 | 
			
		||||
                                    <div class="input-group input-group-merge">
 | 
			
		||||
                                        <div class="input-group-prepend">
 | 
			
		||||
                                            <span class="input-group-text">
 | 
			
		||||
                                                <i class="fa fa-search"></i>
 | 
			
		||||
                                            </span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <input 
 | 
			
		||||
                                            type="text"
 | 
			
		||||
                                            data-input="true"
 | 
			
		||||
                                            class="form-control"
 | 
			
		||||
                                            autocapitalize="default" autocorrect="ON" 
 | 
			
		||||
                                            :placeholder="placeholder"
 | 
			
		||||
                                            :ref="'input-contact-field-' + _uid"
 | 
			
		||||
                                            v-model="search"
 | 
			
		||||
                                            @input="onInput"
 | 
			
		||||
                                            @keyup.enter="onInput"
 | 
			
		||||
                                        />
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            
 | 
			
		||||
                            <ul class="aka-select-menu-options">
 | 
			
		||||
                                <div class="aka-select-menu-option" v-for="(contact, index) in sortContacts" :key="index" @click="onContactSeleted(index, contact.id)">
 | 
			
		||||
                                    <div>
 | 
			
		||||
                                        <strong class="text-strong"><span>{{ contact.name }}</span></strong>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <div class="aka-select-menu-option" v-if="!sortContacts.length">
 | 
			
		||||
                                    <div>
 | 
			
		||||
                                        <strong class="text-strong" v-if="!contacts.length && !search"><span>{{ noDataText }}</span></strong>
 | 
			
		||||
 | 
			
		||||
                                        <strong class="text-strong" v-else><span>{{ noMatchingDataText }}</span></strong>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </ul>
 | 
			
		||||
                            
 | 
			
		||||
                            <div class="aka-select__footer" tabindex="0" @click="onContactCreate">
 | 
			
		||||
                                <span>
 | 
			
		||||
                                    <i class="fas fa-plus"></i> Create a new customer
 | 
			
		||||
                                </span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <div v-else class="invoice-customer__with-customer__bill-to">
 | 
			
		||||
                    <div>
 | 
			
		||||
                        <span class="aka-text aka-text--block-label">Bill to</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="table-responsive">
 | 
			
		||||
                        <table class="table table-borderless p-0">
 | 
			
		||||
                            <tbody>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th class="p-0">
 | 
			
		||||
                                        <strong class="d-block">{{ contact.name }}</strong>
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th class="p-0">
 | 
			
		||||
                                        {{ contact.address }}
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th class="p-0">
 | 
			
		||||
                                        general.tax_number: {{ contact.tax_number }}
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <th class="p-0">
 | 
			
		||||
                                        {{ contact.phone }}
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                                <tr v-if="contact.email">
 | 
			
		||||
                                    <th class="p-0">
 | 
			
		||||
                                        {{ contact.email }}
 | 
			
		||||
                                    </th>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            </tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <button type="button" class="btn btn-link" @click="onContactEdit">Edit Test Customer</button> • <button type="button" class="btn btn-link" @click="onContactList">Choose a different customer</button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <component v-bind:is="add_new_html" @submit="onSubmit" @cancel="onCancel"></component>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import { Select, Option, OptionGroup, ColorPicker } from 'element-ui';
 | 
			
		||||
 | 
			
		||||
import AkauntingModalAddNew from './AkauntingModalAddNew';
 | 
			
		||||
import AkauntingModal from './AkauntingModal';
 | 
			
		||||
import AkauntingMoney from './AkauntingMoney';
 | 
			
		||||
import AkauntingRadioGroup from './forms/AkauntingRadioGroup';
 | 
			
		||||
import AkauntingSelect from './AkauntingSelect';
 | 
			
		||||
import AkauntingDate from './AkauntingDate';
 | 
			
		||||
 | 
			
		||||
import Form from './../plugins/form';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'akaunting-contact-card',
 | 
			
		||||
 | 
			
		||||
    components: {
 | 
			
		||||
        [Select.name]: Select,
 | 
			
		||||
        [Option.name]: Option,
 | 
			
		||||
        [OptionGroup.name]: OptionGroup,
 | 
			
		||||
        [ColorPicker.name]: ColorPicker,
 | 
			
		||||
        AkauntingModalAddNew,
 | 
			
		||||
        AkauntingModal,
 | 
			
		||||
        AkauntingMoney,
 | 
			
		||||
        AkauntingRadioGroup,
 | 
			
		||||
        AkauntingSelect,
 | 
			
		||||
        AkauntingDate,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    props: {
 | 
			
		||||
        placeholder: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'Type a contact name',
 | 
			
		||||
            description: 'Input placeholder'
 | 
			
		||||
        },
 | 
			
		||||
        searchRoute: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: '',
 | 
			
		||||
            description: 'Contact search route'
 | 
			
		||||
        },
 | 
			
		||||
        createRoute: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: '',
 | 
			
		||||
            description: 'Contact create route'
 | 
			
		||||
        },
 | 
			
		||||
        selected: {
 | 
			
		||||
            type: Object,
 | 
			
		||||
            default: function() {
 | 
			
		||||
                return {
 | 
			
		||||
                    index: 0,
 | 
			
		||||
                    key: '',
 | 
			
		||||
                    value: '',
 | 
			
		||||
                    type: 'customer',
 | 
			
		||||
                    id: 0,
 | 
			
		||||
                    name: '',
 | 
			
		||||
                    email: '',
 | 
			
		||||
                    tax_number: '',
 | 
			
		||||
                    currency_code: '',
 | 
			
		||||
                    phone: '',
 | 
			
		||||
                    website: '',
 | 
			
		||||
                    address: '',
 | 
			
		||||
                    reference: '' 
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            description: 'List of Contacts'
 | 
			
		||||
        },
 | 
			
		||||
        contacts: {
 | 
			
		||||
            type: Array,
 | 
			
		||||
            default: () => [],
 | 
			
		||||
            description: 'List of Contacts'
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        addNew: {
 | 
			
		||||
            type: Object,
 | 
			
		||||
            default: function () {
 | 
			
		||||
                return {
 | 
			
		||||
                    text: 'Add New Item',
 | 
			
		||||
                    status: false,
 | 
			
		||||
                    new_text: 'New',
 | 
			
		||||
                    buttons: {}
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            description: "Selectbox Add New Item Feature"
 | 
			
		||||
        },
 | 
			
		||||
        noDataText: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'No Data',
 | 
			
		||||
            description: "Selectbox empty options message"
 | 
			
		||||
        },
 | 
			
		||||
        noMatchingDataText: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'No Matchign Data',
 | 
			
		||||
            description: "Selectbox search option not found item message"
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
        contact_list: [],
 | 
			
		||||
        contact: this.selected,
 | 
			
		||||
        search: '', // search cloumn model
 | 
			
		||||
        show: {
 | 
			
		||||
            contact_selected: false,
 | 
			
		||||
            contact_list: false,
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        form: {},
 | 
			
		||||
        add_new: {
 | 
			
		||||
            text: this.addNew.text,
 | 
			
		||||
            show: false,
 | 
			
		||||
            buttons: this.addNew.buttons,
 | 
			
		||||
        },
 | 
			
		||||
        add_new_html: '',
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        onContactList() {
 | 
			
		||||
            this.show.contact_list = true;
 | 
			
		||||
            this.show.contact_selected = false;
 | 
			
		||||
            this.contact = {};
 | 
			
		||||
 | 
			
		||||
            this.$emit('change', {
 | 
			
		||||
                index: 0,
 | 
			
		||||
                key: '',
 | 
			
		||||
                value: '',
 | 
			
		||||
                type: 'customer',
 | 
			
		||||
                id: 0,
 | 
			
		||||
                name: '',
 | 
			
		||||
                email: '',
 | 
			
		||||
                tax_number: '',
 | 
			
		||||
                currency_code: '',
 | 
			
		||||
                phone: '',
 | 
			
		||||
                website: '',
 | 
			
		||||
                address: '',
 | 
			
		||||
                reference: '' 
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onInput() {
 | 
			
		||||
            window.axios.get(this.searchRoute + 'search="' + this.search + '" limit:10')
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.contact_list = [];
 | 
			
		||||
 | 
			
		||||
                let contacts = response.data.data;
 | 
			
		||||
 | 
			
		||||
                contacts.forEach(function (contact, index) {
 | 
			
		||||
                    this.contact_list.push({
 | 
			
		||||
                        index: index,
 | 
			
		||||
                        key: contact.id,
 | 
			
		||||
                        value: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                        type: (contact.type) ? contact.type : 'customer',
 | 
			
		||||
                        id: contact.id,
 | 
			
		||||
                        name: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                        email: (contact.email) ? contact.email : '',
 | 
			
		||||
                        tax_number: (contact.tax_number) ? contact.tax_number : '',
 | 
			
		||||
                        currency_code: (contact.currency_code) ? contact.currency_code : '',
 | 
			
		||||
                        phone: (contact.phone) ? contact.phone : '',
 | 
			
		||||
                        website: (contact.website) ? contact.website : '',
 | 
			
		||||
                        address: (contact.address) ? contact.address : '',
 | 
			
		||||
                        reference: (contact.reference) ? contact.reference : '' 
 | 
			
		||||
                    });
 | 
			
		||||
                }, this);
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this.$emit('input', this.search);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onContactSeleted(index, contact_id) {
 | 
			
		||||
            this.contact = this.contact_list[index];
 | 
			
		||||
 | 
			
		||||
            this.show.contact_list = false;
 | 
			
		||||
            this.show.contact_selected = true;
 | 
			
		||||
 | 
			
		||||
            this.$emit('change', this.contact);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onContactCreate() {
 | 
			
		||||
            let add_new = this.add_new;
 | 
			
		||||
 | 
			
		||||
            window.axios.get(this.createRoute)
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.show.contact_selected = false;
 | 
			
		||||
                this.show.contact_list = false;
 | 
			
		||||
 | 
			
		||||
                add_new.show = true;
 | 
			
		||||
                add_new.html = response.data.html;
 | 
			
		||||
 | 
			
		||||
                this.add_new_html = Vue.component('add-new-component', function (resolve, reject) {
 | 
			
		||||
                    resolve({
 | 
			
		||||
                        template: '<div><akaunting-modal-add-new :show="add_new.show" @submit="onSubmit" @cancel="onCancel" :buttons="add_new.buttons" :title="add_new.text" :is_component=true :message="add_new.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                        components: {
 | 
			
		||||
                            [Select.name]: Select,
 | 
			
		||||
                            [Option.name]: Option,
 | 
			
		||||
                            [OptionGroup.name]: OptionGroup,
 | 
			
		||||
                            [ColorPicker.name]: ColorPicker,
 | 
			
		||||
                            AkauntingModalAddNew,
 | 
			
		||||
                            AkauntingModal,
 | 
			
		||||
                            AkauntingMoney,
 | 
			
		||||
                            AkauntingRadioGroup,
 | 
			
		||||
                            AkauntingSelect,
 | 
			
		||||
                            AkauntingDate,
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        data: function () {
 | 
			
		||||
                            return {
 | 
			
		||||
                                add_new: add_new,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        methods: {
 | 
			
		||||
                            onSubmit(event) {
 | 
			
		||||
                                this.$emit('submit', event);
 | 
			
		||||
                            },
 | 
			
		||||
 | 
			
		||||
                            onCancel(event) {
 | 
			
		||||
                                this.$emit('cancel', event);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
            .catch(e => {
 | 
			
		||||
                console.log(e);
 | 
			
		||||
            })
 | 
			
		||||
            .finally(function () {
 | 
			
		||||
                // always executed
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onContactEdit() {
 | 
			
		||||
            let add_new = this.add_new;
 | 
			
		||||
            let path = this.createRoute.replace('/create', '/');
 | 
			
		||||
 | 
			
		||||
            path += this.contact.id + '/edit';
 | 
			
		||||
 | 
			
		||||
            window.axios.get(path)
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.show.contact_selected = false;
 | 
			
		||||
                this.show.contact_list = false;
 | 
			
		||||
 | 
			
		||||
                add_new.show = true;
 | 
			
		||||
                add_new.html = response.data.html;
 | 
			
		||||
 | 
			
		||||
                this.add_new_html = Vue.component('add-new-component', function (resolve, reject) {
 | 
			
		||||
                    resolve({
 | 
			
		||||
                        template: '<div><akaunting-modal-add-new :show="add_new.show" @submit="onSubmit" @cancel="onCancel" :buttons="add_new.buttons" :title="add_new.text" :is_component=true :message="add_new.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                        components: {
 | 
			
		||||
                            [Select.name]: Select,
 | 
			
		||||
                            [Option.name]: Option,
 | 
			
		||||
                            [OptionGroup.name]: OptionGroup,
 | 
			
		||||
                            [ColorPicker.name]: ColorPicker,
 | 
			
		||||
                            AkauntingModalAddNew,
 | 
			
		||||
                            AkauntingModal,
 | 
			
		||||
                            AkauntingMoney,
 | 
			
		||||
                            AkauntingRadioGroup,
 | 
			
		||||
                            AkauntingSelect,
 | 
			
		||||
                            AkauntingDate,
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        data: function () {
 | 
			
		||||
                            return {
 | 
			
		||||
                                add_new: add_new,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        methods: {
 | 
			
		||||
                            onSubmit(event) {
 | 
			
		||||
                                this.$emit('submit', event);
 | 
			
		||||
                            },
 | 
			
		||||
 | 
			
		||||
                            onCancel(event) {
 | 
			
		||||
                                this.$emit('cancel', event);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
            .catch(e => {
 | 
			
		||||
                console.log(e);
 | 
			
		||||
            })
 | 
			
		||||
            .finally(function () {
 | 
			
		||||
                // always executed
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onSubmit(event) {
 | 
			
		||||
            this.form = event;
 | 
			
		||||
 | 
			
		||||
            this.loading = true;
 | 
			
		||||
 | 
			
		||||
            let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
            FormData.prototype.appendRecursive = function(data, wrapper = null) {
 | 
			
		||||
                for(var name in data) {
 | 
			
		||||
                    if (wrapper) {
 | 
			
		||||
                        if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                            this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                            this.appendRecursive(data[name], name);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.append(name, data[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let form_data = new FormData();
 | 
			
		||||
            form_data.appendRecursive(data);
 | 
			
		||||
 | 
			
		||||
            window.axios({
 | 
			
		||||
                method: this.form.method,
 | 
			
		||||
                url: this.form.action,
 | 
			
		||||
                data: form_data,
 | 
			
		||||
                headers: {
 | 
			
		||||
                    'X-CSRF-TOKEN': window.Laravel.csrfToken,
 | 
			
		||||
                    'X-Requested-With': 'XMLHttpRequest',
 | 
			
		||||
                    'Content-Type': 'multipart/form-data'
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                if (response.data.success) {
 | 
			
		||||
                    let contact = response.data.data;
 | 
			
		||||
 | 
			
		||||
                    this.contact = contact;
 | 
			
		||||
 | 
			
		||||
                    this.show.contact_list = false;
 | 
			
		||||
                    this.show.contact_selected = true;
 | 
			
		||||
 | 
			
		||||
                    this.add_new.show = false;
 | 
			
		||||
 | 
			
		||||
                    this.add_new.html = '';
 | 
			
		||||
                    this.add_new_html = null;
 | 
			
		||||
 | 
			
		||||
                    this.$emit('new', contact);
 | 
			
		||||
 | 
			
		||||
                    this.$emit('change', this.contact);
 | 
			
		||||
 | 
			
		||||
                    let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
                    documentClasses.remove("modal-open");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
                this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                console.log(error);
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onCancel() {
 | 
			
		||||
            this.add_new.show = false;
 | 
			
		||||
            this.add_new.html = null;
 | 
			
		||||
            this.add_new_html = null;
 | 
			
		||||
 | 
			
		||||
            let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
            documentClasses.remove("modal-open");
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        closeIfClickedOutside(event) {
 | 
			
		||||
            if (!document.getElementById('select-contact-card-' + this._uid).contains(event.target) && event.target.className != 'btn btn-link') {
 | 
			
		||||
                this.show.contact_list = false;
 | 
			
		||||
 | 
			
		||||
                document.removeEventListener('click', this.closeIfClickedOutside);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    created() {
 | 
			
		||||
        // Option set sort_option data
 | 
			
		||||
        if (!Array.isArray(this.contacts)) {
 | 
			
		||||
            let index = 0;
 | 
			
		||||
 | 
			
		||||
            for (const [key, value] of Object.entries(this.contacts)) {
 | 
			
		||||
                this.contact_list.push({
 | 
			
		||||
                    index: index,
 | 
			
		||||
                    key: key,
 | 
			
		||||
                    value: value,
 | 
			
		||||
                    type: 'customer',
 | 
			
		||||
                    id: key,
 | 
			
		||||
                    name: value,
 | 
			
		||||
                    email: '',
 | 
			
		||||
                    tax_number: '',
 | 
			
		||||
                    currency_code: '',
 | 
			
		||||
                    phone: '',
 | 
			
		||||
                    website: '',
 | 
			
		||||
                    address: '',
 | 
			
		||||
                    reference: '' 
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                index++;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this.contacts.forEach(function (contact, index) {
 | 
			
		||||
                this.contact_list.push({
 | 
			
		||||
                    index: index,
 | 
			
		||||
                    key: contact.id,
 | 
			
		||||
                    value: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                    type: (contact.type) ? contact.type : 'customer',
 | 
			
		||||
                    id: contact.id,
 | 
			
		||||
                    name: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                    email: (contact.email) ? contact.email : '',
 | 
			
		||||
                    tax_number: (contact.tax_number) ? contact.tax_number : '',
 | 
			
		||||
                    currency_code: (contact.currency_code) ? contact.currency_code : '',
 | 
			
		||||
                    phone: (contact.phone) ? contact.phone : '',
 | 
			
		||||
                    website: (contact.website) ? contact.website : '',
 | 
			
		||||
                    address: (contact.address) ? contact.address : '',
 | 
			
		||||
                    reference: (contact.reference) ? contact.reference : '' 
 | 
			
		||||
                });
 | 
			
		||||
            }, this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.selected.id) {
 | 
			
		||||
            this.show.contact_list = false;
 | 
			
		||||
            this.show.contact_selected = true;
 | 
			
		||||
 | 
			
		||||
            this.$emit('change', this.contact);
 | 
			
		||||
        }
 | 
			
		||||
  } ,
 | 
			
		||||
 | 
			
		||||
    computed: {
 | 
			
		||||
        sortContacts() {
 | 
			
		||||
            this.contact_list.sort(function (a, b) {
 | 
			
		||||
                var nameA = a.value.toUpperCase(); // ignore upper and lowercase
 | 
			
		||||
                var nameB = b.value.toUpperCase(); // ignore upper and lowercase
 | 
			
		||||
 | 
			
		||||
                if (nameA < nameB) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (nameA > nameB) {
 | 
			
		||||
                    return 1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // names must be equal
 | 
			
		||||
                return 0;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return this.contact_list.filter(contact => {
 | 
			
		||||
                return contact.value.toLowerCase().includes(this.search.toLowerCase())
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    watch: {
 | 
			
		||||
        show: {
 | 
			
		||||
            handler: function(newValue) {
 | 
			
		||||
                if (newValue) {
 | 
			
		||||
                    document.addEventListener('click', this.closeIfClickedOutside);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            deep: true
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										194
									
								
								resources/assets/js/components/AkauntingEditItemColumns.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								resources/assets/js/components/AkauntingEditItemColumns.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="item-columns-edit">
 | 
			
		||||
        <i class="fas fa-pencil-alt"></i>
 | 
			
		||||
        <button 
 | 
			
		||||
            type="button"
 | 
			
		||||
            class="btn-aka-link"
 | 
			
		||||
            @click="onEditItemColumns">
 | 
			
		||||
            Edit columns
 | 
			
		||||
        </button>
 | 
			
		||||
 | 
			
		||||
        <component v-bind:is="edit_html" @submit="onSubmit" @cancel="onCancel"></component>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import AkauntingModalAddNew from './AkauntingModalAddNew';
 | 
			
		||||
 | 
			
		||||
import Form from './../plugins/form';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'akaunting-edit-item-columns',
 | 
			
		||||
 | 
			
		||||
    components: {
 | 
			
		||||
        AkauntingModalAddNew,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
  props: {
 | 
			
		||||
    placeholder: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'Type an item name',
 | 
			
		||||
      description: 'Input placeholder'
 | 
			
		||||
    },
 | 
			
		||||
    type: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'sale',
 | 
			
		||||
      description: 'Show item price'
 | 
			
		||||
    },
 | 
			
		||||
    editColumn: {
 | 
			
		||||
        type: Object,
 | 
			
		||||
        default: function () {
 | 
			
		||||
            return {
 | 
			
		||||
                text: 'Add New Item',
 | 
			
		||||
                status: false,
 | 
			
		||||
                new_text: 'New',
 | 
			
		||||
                buttons: {}
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        description: "Selectbox Add New Item Feature"
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      form: {},
 | 
			
		||||
      edit_column: {
 | 
			
		||||
          text: this.editColumn.text,
 | 
			
		||||
          show: false,
 | 
			
		||||
          buttons: this.editColumn.buttons,
 | 
			
		||||
      },
 | 
			
		||||
      edit_html: '',
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    onEditItemColumns() {
 | 
			
		||||
      let edit_column = this.edit_column;
 | 
			
		||||
 | 
			
		||||
      window.axios.get(url + '/modals/invoices/item-columns/edit')
 | 
			
		||||
      .then(response => {
 | 
			
		||||
          edit_column.show = true;
 | 
			
		||||
          edit_column.html = response.data.html;
 | 
			
		||||
 | 
			
		||||
          this.edit_html = Vue.component('add-new-component', function (resolve, reject) {
 | 
			
		||||
              resolve({
 | 
			
		||||
                  template: '<div><akaunting-modal-add-new :show="edit_column.show" @submit="onSubmit" @cancel="onCancel" :buttons="edit_column.buttons" :title="edit_column.text" :is_component=true :message="edit_column.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                  components: {
 | 
			
		||||
                    AkauntingModalAddNew,
 | 
			
		||||
                  },
 | 
			
		||||
 | 
			
		||||
                  data: function () {
 | 
			
		||||
                      return {
 | 
			
		||||
                          edit_column: edit_column,
 | 
			
		||||
                      }
 | 
			
		||||
                  },
 | 
			
		||||
 | 
			
		||||
                  methods: {
 | 
			
		||||
                      onSubmit(event) {
 | 
			
		||||
                          this.$emit('submit', event);
 | 
			
		||||
                      },
 | 
			
		||||
 | 
			
		||||
                      onCancel(event) {
 | 
			
		||||
                          this.$emit('cancel', event);
 | 
			
		||||
                      }
 | 
			
		||||
                  }
 | 
			
		||||
              })
 | 
			
		||||
          });
 | 
			
		||||
      })
 | 
			
		||||
      .catch(e => {
 | 
			
		||||
          console.log(e);
 | 
			
		||||
      })
 | 
			
		||||
      .finally(function () {
 | 
			
		||||
          // always executed
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onSubmit(event) {
 | 
			
		||||
        this.form = event;
 | 
			
		||||
 | 
			
		||||
        this.loading = true;
 | 
			
		||||
 | 
			
		||||
        let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
        FormData.prototype.appendRecursive = function(data, wrapper = null) {
 | 
			
		||||
            for(var name in data) {
 | 
			
		||||
                if (wrapper) {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], name);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(name, data[name]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let form_data = new FormData();
 | 
			
		||||
        form_data.appendRecursive(data);
 | 
			
		||||
 | 
			
		||||
        window.axios({
 | 
			
		||||
            method: this.form.method,
 | 
			
		||||
            url: this.form.action,
 | 
			
		||||
            data: form_data,
 | 
			
		||||
            headers: {
 | 
			
		||||
                'X-CSRF-TOKEN': window.Laravel.csrfToken,
 | 
			
		||||
                'X-Requested-With': 'XMLHttpRequest',
 | 
			
		||||
                'Content-Type': 'multipart/form-data'
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .then(response => {
 | 
			
		||||
            this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
            if (response.data.success) {
 | 
			
		||||
                let contact = response.data.data;
 | 
			
		||||
 | 
			
		||||
                this.contact_list.push({
 | 
			
		||||
                    key: contact.id,
 | 
			
		||||
                    value: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                    type: (contact.type) ? contact.type : 'customer',
 | 
			
		||||
                    id: contact.id,
 | 
			
		||||
                    name: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                    address: (contact.address) ? contact.address : '' 
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                this.edit_column.show = false;
 | 
			
		||||
 | 
			
		||||
                this.edit_column.html = '';
 | 
			
		||||
                this.edit_html = null;
 | 
			
		||||
 | 
			
		||||
                this.$emit('new', contact);
 | 
			
		||||
 | 
			
		||||
                let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
                documentClasses.remove("modal-open");
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        .catch(error => {
 | 
			
		||||
            this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
            this.form.onFail(error);
 | 
			
		||||
 | 
			
		||||
            this.method_show_html = error.message;
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    onCancel() {
 | 
			
		||||
        this.edit_column.show = false;
 | 
			
		||||
        this.edit_column.html = null;
 | 
			
		||||
        this.edit_html = null;
 | 
			
		||||
 | 
			
		||||
        let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
        documentClasses.remove("modal-open");
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										532
									
								
								resources/assets/js/components/AkauntingItemButton.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										532
									
								
								resources/assets/js/components/AkauntingItemButton.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,532 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div :id="'select-item-button-' + _uid" class="product-select">
 | 
			
		||||
        <div class="aka-select aka-select--fluid" :class="[{'is-open': show.item_list}]" tabindex="-1">
 | 
			
		||||
            <div>
 | 
			
		||||
                <button type="button" class="btn btn-link w-100" @click="onItemList">
 | 
			
		||||
                    <i class="fas fa-plus-circle"></i>   Add an item
 | 
			
		||||
                </button>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="aka-select-menu" v-if="show.item_list">
 | 
			
		||||
                <div class="aka-select-search-container">
 | 
			
		||||
                    <span class="aka-prefixed-input aka-prefixed-input--fluid">
 | 
			
		||||
                        <div class="input-group input-group-merge">
 | 
			
		||||
                            <div class="input-group-prepend">
 | 
			
		||||
                                <span class="input-group-text">
 | 
			
		||||
                                    <i class="fa fa-search"></i>
 | 
			
		||||
                                </span>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <input 
 | 
			
		||||
                                type="text"
 | 
			
		||||
                                data-input="true"
 | 
			
		||||
                                class="form-control"
 | 
			
		||||
                                autocapitalize="default" autocorrect="ON" 
 | 
			
		||||
                                :placeholder="placeholder"
 | 
			
		||||
                                :ref="'input-contact-field-' + _uid"
 | 
			
		||||
                                v-model="search"
 | 
			
		||||
                                @input="onInput"
 | 
			
		||||
                                @keyup.enter="onInput"
 | 
			
		||||
                            />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <ul class="aka-select-menu-options">
 | 
			
		||||
                    <div class="aka-select-menu-option" v-for="(item, index) in sortItems" :key="index" @click="onItemSeleted(index, item.id)">
 | 
			
		||||
                        <div class="product-select__product">
 | 
			
		||||
                            <div class="product-select__product__column product-select__product__info">
 | 
			
		||||
                                <b class="product-select__product__info__name"><span>{{ item.name }}</span></b>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="product-select__product__column product-select__product__price">
 | 
			
		||||
                                {{ item.price }}
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="aka-select-menu-option" v-if="!sortItems.length">
 | 
			
		||||
                        <div>
 | 
			
		||||
                            <strong class="text-strong" v-if="!items.length && !search"><span>{{ noDataText }}</span></strong>
 | 
			
		||||
 | 
			
		||||
                            <strong class="text-strong" v-else><span>{{ noMatchingDataText }}</span></strong>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </ul>
 | 
			
		||||
 | 
			
		||||
                <div class="aka-select__footer" tabindex="0" @click="onItemCreate">
 | 
			
		||||
                    <span>
 | 
			
		||||
                        <i class="fas fa-plus"></i> Create a new item
 | 
			
		||||
                    </span>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import { Select, Option, OptionGroup, ColorPicker } from 'element-ui';
 | 
			
		||||
 | 
			
		||||
import {Money} from 'v-money';
 | 
			
		||||
import AkauntingModalAddNew from './AkauntingModalAddNew';
 | 
			
		||||
import AkauntingModal from './AkauntingModal';
 | 
			
		||||
import AkauntingMoney from './AkauntingMoney';
 | 
			
		||||
import AkauntingRadioGroup from './forms/AkauntingRadioGroup';
 | 
			
		||||
import AkauntingSelect from './AkauntingSelect';
 | 
			
		||||
import AkauntingDate from './AkauntingDate';
 | 
			
		||||
 | 
			
		||||
import Form from './../plugins/form';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    name: 'akaunting-item-button',
 | 
			
		||||
 | 
			
		||||
    components: {
 | 
			
		||||
        [Select.name]: Select,
 | 
			
		||||
        [Option.name]: Option,
 | 
			
		||||
        [OptionGroup.name]: OptionGroup,
 | 
			
		||||
        [ColorPicker.name]: ColorPicker,
 | 
			
		||||
        AkauntingModalAddNew,
 | 
			
		||||
        AkauntingModal,
 | 
			
		||||
        AkauntingMoney,
 | 
			
		||||
        AkauntingRadioGroup,
 | 
			
		||||
        AkauntingSelect,
 | 
			
		||||
        AkauntingDate,
 | 
			
		||||
        Money,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    props: {
 | 
			
		||||
        placeholder: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'Type an item name',
 | 
			
		||||
            description: 'Input placeholder'
 | 
			
		||||
        },
 | 
			
		||||
        type: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'sale',
 | 
			
		||||
            description: 'Show item price'
 | 
			
		||||
        },
 | 
			
		||||
        items: {
 | 
			
		||||
            type: Array,
 | 
			
		||||
            default: () => [],
 | 
			
		||||
            description: 'List of Items'
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        addNew: {
 | 
			
		||||
            type: Object,
 | 
			
		||||
            default: function () {
 | 
			
		||||
                return {
 | 
			
		||||
                    text: 'Add New Item',
 | 
			
		||||
                    status: false,
 | 
			
		||||
                    new_text: 'New',
 | 
			
		||||
                    buttons: {}
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            description: "Selectbox Add New Item Feature"
 | 
			
		||||
        },
 | 
			
		||||
        noDataText: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'No Data',
 | 
			
		||||
            description: "Selectbox empty options message"
 | 
			
		||||
        },
 | 
			
		||||
        noMatchingDataText: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default: 'No Matchign Data',
 | 
			
		||||
            description: "Selectbox search option not found item message"
 | 
			
		||||
        },
 | 
			
		||||
        currency: {
 | 
			
		||||
            type: Object,
 | 
			
		||||
            default: function () {
 | 
			
		||||
                return {
 | 
			
		||||
                    decimal_mark: '.',
 | 
			
		||||
                    thousands_separator: ',',
 | 
			
		||||
                    symbol_first: 1,
 | 
			
		||||
                    symbol: '$',
 | 
			
		||||
                    precision: 2,
 | 
			
		||||
                };
 | 
			
		||||
            },
 | 
			
		||||
            description: "Default currency"
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            item_list: [],
 | 
			
		||||
            selected_items: [],
 | 
			
		||||
            search: '', // search cloumn model
 | 
			
		||||
            show: {
 | 
			
		||||
                item_selected: false,
 | 
			
		||||
                item_list: false,
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            form: {},
 | 
			
		||||
            add_new: {
 | 
			
		||||
                text: this.addNew.text,
 | 
			
		||||
                show: false,
 | 
			
		||||
                buttons: this.addNew.buttons,
 | 
			
		||||
            },
 | 
			
		||||
            add_new_html: '',
 | 
			
		||||
            money: {
 | 
			
		||||
                decimal: this.currency.decimal_mark,
 | 
			
		||||
                thousands: this.currency.thousands_separator,
 | 
			
		||||
                prefix: (this.currency.symbol_first) ? this.currency.symbol : '',
 | 
			
		||||
                suffix: (!this.currency.symbol_first) ? this.currency.symbol : '',
 | 
			
		||||
                precision: parseInt(this.currency.precision),
 | 
			
		||||
                masked: this.masked
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        onItemList() {
 | 
			
		||||
            this.show.item_list = true;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onInput() {
 | 
			
		||||
            window.axios.get(url + '/common/items?search="' + this.search + '" limit:10')
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.item_list = [];
 | 
			
		||||
 | 
			
		||||
                let items = response.data.data;
 | 
			
		||||
 | 
			
		||||
                items.forEach(function (item, index) {
 | 
			
		||||
                    this.item_list.push({
 | 
			
		||||
                        index: index,
 | 
			
		||||
                        key: item.id,
 | 
			
		||||
                        value: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
 | 
			
		||||
                        type: this.type,
 | 
			
		||||
                        id: item.id,
 | 
			
		||||
                        name: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
 | 
			
		||||
                        price: (item.price) ? item.price : (this.type == 'sale') ? item.sale_price : item.purchase_price,
 | 
			
		||||
                        tax_ids: (item.tax_ids) ? item.tax_ids : [],
 | 
			
		||||
                    });
 | 
			
		||||
                }, this);
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this.$emit('input', this.search);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onItemSeleted(index, item_id) {
 | 
			
		||||
            let item = this.item_list[index];
 | 
			
		||||
 | 
			
		||||
            this.selected_items.push(item);
 | 
			
		||||
 | 
			
		||||
            this.$emit('item', item);
 | 
			
		||||
            this.$emit('items', this.selected_items);
 | 
			
		||||
 | 
			
		||||
            this.show.item_selected = false;
 | 
			
		||||
            this.show.item_list = false;
 | 
			
		||||
            this.search = '';
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onItemCreate() {
 | 
			
		||||
            this.show.item_selected = false;
 | 
			
		||||
            this.show.item_list = false;
 | 
			
		||||
            
 | 
			
		||||
            let add_new = this.add_new;
 | 
			
		||||
 | 
			
		||||
            window.axios.get(this.createRoute)
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                add_new.show = true;
 | 
			
		||||
                add_new.html = response.data.html;
 | 
			
		||||
 | 
			
		||||
                this.add_new_html = Vue.component('add-new-component', function (resolve, reject) {
 | 
			
		||||
                    resolve({
 | 
			
		||||
                        template: '<div><akaunting-modal-add-new :show="add_new.show" @submit="onSubmit" @cancel="onCancel" :buttons="add_new.buttons" :title="add_new.text" :is_component=true :message="add_new.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                        components: {
 | 
			
		||||
                            [Select.name]: Select,
 | 
			
		||||
                            [Option.name]: Option,
 | 
			
		||||
                            [OptionGroup.name]: OptionGroup,
 | 
			
		||||
                            [ColorPicker.name]: ColorPicker,
 | 
			
		||||
                            AkauntingModalAddNew,
 | 
			
		||||
                            AkauntingModal,
 | 
			
		||||
                            AkauntingMoney,
 | 
			
		||||
                            AkauntingRadioGroup,
 | 
			
		||||
                            AkauntingSelect,
 | 
			
		||||
                            AkauntingDate,
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        data: function () {
 | 
			
		||||
                            return {
 | 
			
		||||
                                add_new: add_new,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        methods: {
 | 
			
		||||
                            onSubmit(event) {
 | 
			
		||||
                                this.$emit('submit', event);
 | 
			
		||||
                            },
 | 
			
		||||
 | 
			
		||||
                            onCancel(event) {
 | 
			
		||||
                                this.$emit('cancel', event);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
            .catch(e => {
 | 
			
		||||
                console.log(e);
 | 
			
		||||
            })
 | 
			
		||||
            .finally(function () {
 | 
			
		||||
                // always executed
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onSubmit(event) {
 | 
			
		||||
            this.form = event;
 | 
			
		||||
 | 
			
		||||
            this.loading = true;
 | 
			
		||||
 | 
			
		||||
            let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
            FormData.prototype.appendRecursive = function(data, wrapper = null) {
 | 
			
		||||
                for(var name in data) {
 | 
			
		||||
                    if (wrapper) {
 | 
			
		||||
                        if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                            this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                            this.appendRecursive(data[name], name);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.append(name, data[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let form_data = new FormData();
 | 
			
		||||
            form_data.appendRecursive(data);
 | 
			
		||||
 | 
			
		||||
            window.axios({
 | 
			
		||||
                method: this.form.method,
 | 
			
		||||
                url: this.form.action,
 | 
			
		||||
                data: form_data,
 | 
			
		||||
                headers: {
 | 
			
		||||
                    'X-CSRF-TOKEN': window.Laravel.csrfToken,
 | 
			
		||||
                    'X-Requested-With': 'XMLHttpRequest',
 | 
			
		||||
                    'Content-Type': 'multipart/form-data'
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                if (response.data.success) {
 | 
			
		||||
                    let contact = response.data.data;
 | 
			
		||||
 | 
			
		||||
                    this.contact_list.push({
 | 
			
		||||
                        key: contact.id,
 | 
			
		||||
                        value: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                        type: (contact.type) ? contact.type : 'customer',
 | 
			
		||||
                        id: contact.id,
 | 
			
		||||
                        name: (contact.title) ? contact.title : (contact.display_name) ? contact.display_name : contact.name,
 | 
			
		||||
                        address: (contact.address) ? contact.address : '' 
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    this.add_new.show = false;
 | 
			
		||||
 | 
			
		||||
                    this.add_new.html = '';
 | 
			
		||||
                    this.add_new_html = null;
 | 
			
		||||
 | 
			
		||||
                    this.$emit('new', contact);
 | 
			
		||||
 | 
			
		||||
                    let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
                    documentClasses.remove("modal-open");
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
                this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                this.form.onFail(error);
 | 
			
		||||
 | 
			
		||||
                this.method_show_html = error.message;
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onCancel() {
 | 
			
		||||
            this.add_new.show = false;
 | 
			
		||||
            this.add_new.html = null;
 | 
			
		||||
            this.add_new_html = null;
 | 
			
		||||
 | 
			
		||||
            let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
            documentClasses.remove("modal-open");
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        closeIfClickedOutside(event) {
 | 
			
		||||
            if (!document.getElementById('select-item-button-' + this._uid).contains(event.target)) {
 | 
			
		||||
                this.show.item_selected = false;
 | 
			
		||||
                this.show.item_list = false;
 | 
			
		||||
                this.search = '';
 | 
			
		||||
 | 
			
		||||
                document.removeEventListener('click', this.closeIfClickedOutside);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    created() {
 | 
			
		||||
        // Option set sort_option data
 | 
			
		||||
        if (!Array.isArray(this.items)) {
 | 
			
		||||
            let index = 0;
 | 
			
		||||
 | 
			
		||||
            for (const [key, value] of Object.entries(this.items)) {
 | 
			
		||||
                this.item_list.push({
 | 
			
		||||
                    index: index,
 | 
			
		||||
                    key: key,
 | 
			
		||||
                    value: value,
 | 
			
		||||
                    type: 'item',
 | 
			
		||||
                    id: key,
 | 
			
		||||
                    name: value,
 | 
			
		||||
                    price: 0,
 | 
			
		||||
                    tax_ids: [], 
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                index++;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this.items.forEach(function (item, index) {
 | 
			
		||||
                this.item_list.push({
 | 
			
		||||
                    index: index,
 | 
			
		||||
                    key: item.id,
 | 
			
		||||
                    value: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
 | 
			
		||||
                    type: this.type,
 | 
			
		||||
                    id: item.id,
 | 
			
		||||
                    name: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name,
 | 
			
		||||
                    price: (item.price) ? item.price : (this.type == 'sale') ? item.sale_price : item.purchase_price,
 | 
			
		||||
                    tax_ids: (item.tax_ids) ? item.tax_ids : [],
 | 
			
		||||
                });
 | 
			
		||||
            }, this);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    computed: {
 | 
			
		||||
        sortItems() {
 | 
			
		||||
            this.item_list.sort(function (a, b) {
 | 
			
		||||
                var nameA = a.value.toUpperCase(); // ignore upper and lowercase
 | 
			
		||||
                var nameB = b.value.toUpperCase(); // ignore upper and lowercase
 | 
			
		||||
 | 
			
		||||
                if (nameA < nameB) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (nameA > nameB) {
 | 
			
		||||
                    return 1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // names must be equal
 | 
			
		||||
                return 0;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return this.item_list.filter(item => {
 | 
			
		||||
                return item.value.toLowerCase().includes(this.search.toLowerCase())
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    watch: {
 | 
			
		||||
        show: {
 | 
			
		||||
            handler: function(newValue) {
 | 
			
		||||
                if (newValue) {
 | 
			
		||||
                    document.addEventListener('click', this.closeIfClickedOutside);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            deep: true
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.aka-select.aka-select--fluid {
 | 
			
		||||
    min-width: 160px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.aka-select.aka-select--fluid {
 | 
			
		||||
    max-width: 96%;
 | 
			
		||||
    min-width: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select .aka-select-menu {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    min-width: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    border-top-left-radius: 0;
 | 
			
		||||
    border-top-right-radius: 0;
 | 
			
		||||
    border-top-width: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.aka-select-menu {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    margin: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    text-align: left;
 | 
			
		||||
    display: block;
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 110%;
 | 
			
		||||
    z-index: 1000;
 | 
			
		||||
    min-width: 100%;
 | 
			
		||||
    padding: 8px 0;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    color: #1c252c;
 | 
			
		||||
    background-color: white;
 | 
			
		||||
    box-shadow: 0 0 0 1px rgba(77,101,117,0.1), 0 3px 10px 0 rgba(77,101,117,0.2);
 | 
			
		||||
    -webkit-transform-origin: 0 0;
 | 
			
		||||
    transform-origin: 0 0;
 | 
			
		||||
    height: 0;
 | 
			
		||||
    -webkit-transform: translateY(4px);
 | 
			
		||||
    transform: translateY(4px);
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    top: 100%;
 | 
			
		||||
    border-top: 0;
 | 
			
		||||
    border-top-left-radius: 0;
 | 
			
		||||
    border-top-right-radius: 0;
 | 
			
		||||
    -webkit-transform: translateY(0);
 | 
			
		||||
    transform: translateY(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select .aka-select.aka-select--fluid.is-open {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select__product {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select__product__column {
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select__product__price {
 | 
			
		||||
    width: 135px;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
.product-select__product__info__description, .product-select__product__info__name {
 | 
			
		||||
    width: 710px;
 | 
			
		||||
    display: block;
 | 
			
		||||
    text-overflow: ellipsis;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.product-select__product__column {
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div class="form-group"
 | 
			
		||||
    <div v-if="!rowInput" class="form-group"
 | 
			
		||||
        :class="[{'has-error': error}, {'required': required}, {'readonly': readonly}, {'disabled': disabled}, col]">
 | 
			
		||||
        <label v-if="title" :for="name" class="form-control-label">{{ title }}</label>
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +15,26 @@
 | 
			
		||||
 | 
			
		||||
        <div class="invalid-feedback d-block" v-if="error" v-html="error"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div v-else
 | 
			
		||||
        :class="[{'has-error': error}, {'required': required}, {'readonly': readonly}, {'disabled': disabled}, col]">
 | 
			
		||||
        <label v-if="title" :for="name" class="form-control-label">{{ title }}</label>
 | 
			
		||||
 | 
			
		||||
        <div v-if="icon" class="input-group input-group-merge" :class="group_class">
 | 
			
		||||
            <div v-if="icon" class="input-group-prepend">
 | 
			
		||||
                <span class="input-group-text">
 | 
			
		||||
                    <i :class="'fa fa-' + icon"></i>
 | 
			
		||||
                </span>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <money :name="name" @input="input" :placeholder="placeholder" v-bind="money" :value="model" :disabled="disabled" :masked="masked" class="form-control"></money>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <money v-else :name="name" @input="input" :placeholder="placeholder" v-bind="money" :value="model" :disabled="disabled" :masked="masked" class="form-control"></money>
 | 
			
		||||
 | 
			
		||||
        <div class="invalid-feedback d-block" v-if="error" v-html="error"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
@@ -109,6 +129,11 @@ export default {
 | 
			
		||||
            default: false,
 | 
			
		||||
            description: "Money result value"
 | 
			
		||||
        },
 | 
			
		||||
        rowInput: {
 | 
			
		||||
            type: Boolean,
 | 
			
		||||
            default: false,
 | 
			
		||||
            description: "Money result value"
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    data() {
 | 
			
		||||
 
 | 
			
		||||
@@ -747,6 +747,26 @@ export default {
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    watch: {
 | 
			
		||||
        selected: function (selected) {
 | 
			
		||||
            if (!this.multiple) {
 | 
			
		||||
                this.selected = selected.toString();
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        value: function (selected) {
 | 
			
		||||
            this.selected = selected;
 | 
			
		||||
 | 
			
		||||
            this.change();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        model: function (selected) {
 | 
			
		||||
            this.selected = selected;
 | 
			
		||||
 | 
			
		||||
            this.change();
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								resources/assets/js/mixins/global.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								resources/assets/js/mixins/global.js
									
									
									
									
										vendored
									
									
								
							@@ -3,6 +3,10 @@ import Vue from 'vue';
 | 
			
		||||
import axios from 'axios';
 | 
			
		||||
 | 
			
		||||
import DropzoneFileUpload from './../components/Inputs/DropzoneFileUpload';
 | 
			
		||||
import AkauntingContactCard from './../components/AkauntingContactCard';
 | 
			
		||||
import AkauntingCompanyEdit from './../components/AkauntingCompanyEdit';
 | 
			
		||||
import AkauntingEditItemColumns from './../components/AkauntingEditItemColumns';
 | 
			
		||||
import AkauntingItemButton from './../components/AkauntingItemButton';
 | 
			
		||||
import AkauntingSearch from './../components/AkauntingSearch';
 | 
			
		||||
import AkauntingModal from './../components/AkauntingModal';
 | 
			
		||||
import AkauntingMoney from './../components/AkauntingMoney';
 | 
			
		||||
@@ -27,6 +31,10 @@ import { concat } from 'lodash';
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        DropzoneFileUpload,
 | 
			
		||||
        AkauntingContactCard,
 | 
			
		||||
        AkauntingCompanyEdit,
 | 
			
		||||
        AkauntingEditItemColumns,
 | 
			
		||||
        AkauntingItemButton,
 | 
			
		||||
        AkauntingSearch,
 | 
			
		||||
        AkauntingRadioGroup,
 | 
			
		||||
        AkauntingSelect,
 | 
			
		||||
@@ -51,7 +59,7 @@ export default {
 | 
			
		||||
    data: function () {
 | 
			
		||||
        return {
 | 
			
		||||
            component: '',
 | 
			
		||||
            currency: null,
 | 
			
		||||
            currency: null
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -391,5 +399,17 @@ export default {
 | 
			
		||||
                })
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        // Change Contact Card set form fields..
 | 
			
		||||
        onChangeContactCard(contact) {
 | 
			
		||||
            this.form.contact_id = contact.id;
 | 
			
		||||
            this.form.contact_name = contact.name;
 | 
			
		||||
            this.form.contact_email = contact.email;
 | 
			
		||||
            this.form.contact_tax_number = contact.tax_number;
 | 
			
		||||
            this.form.contact_phone = contact.phone;
 | 
			
		||||
            this.form.contact_address = contact.address;
 | 
			
		||||
 | 
			
		||||
            this.form.currency_code = contact.currency_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								resources/assets/js/plugins/form.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								resources/assets/js/plugins/form.js
									
									
									
									
										vendored
									
									
								
							@@ -23,6 +23,43 @@ export default class Form {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
            if (name != null && name.indexOf('.') != '-1') {
 | 
			
		||||
                let partial_name = name.split('.');
 | 
			
		||||
 | 
			
		||||
                switch(partial_name.length) {
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 3:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 4:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 5:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]][partial_name[4]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            if (form_element.getAttribute('data-item')) {
 | 
			
		||||
                if (!this['items']) {
 | 
			
		||||
                    var item = {};
 | 
			
		||||
@@ -121,6 +158,43 @@ export default class Form {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /*
 | 
			
		||||
            if (name != null && name.indexOf('.') != '-1') {
 | 
			
		||||
                let partial_name = name.split('.');
 | 
			
		||||
 | 
			
		||||
                switch(partial_name.length) {
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 3:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 4:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 5:
 | 
			
		||||
                        this[partial_name[0]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]] = [];
 | 
			
		||||
                        this[partial_name[0]][partial_name[1]][partial_name[2]][partial_name[3]][partial_name[4]] = '';
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            */
 | 
			
		||||
 | 
			
		||||
            if (form_element.getAttribute('data-item')) {
 | 
			
		||||
                if (!this['items']) {
 | 
			
		||||
                    var item = {};
 | 
			
		||||
@@ -275,13 +349,13 @@ export default class Form {
 | 
			
		||||
        FormData.prototype.appendRecursive = function(data, wrapper = null) {  
 | 
			
		||||
            for(var name in data) {
 | 
			
		||||
                if (wrapper) {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || Array.isArray(data[name])) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                    if ((typeof data[name] == 'object' || Array.isArray(data[name])) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                        this.appendRecursive(data[name], name);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.append(name, data[name]);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										796
									
								
								resources/assets/js/views/common/documents.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										796
									
								
								resources/assets/js/views/common/documents.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,796 @@
 | 
			
		||||
/**
 | 
			
		||||
 * First we will load all of this project's JavaScript dependencies which
 | 
			
		||||
 * includes Vue and other libraries. It is a great starting point when
 | 
			
		||||
 * building robust, powerful web applications using Vue and Laravel.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
require('./../../bootstrap');
 | 
			
		||||
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import DashboardPlugin from './../../plugins/dashboard-plugin';
 | 
			
		||||
 | 
			
		||||
import Global from './../../mixins/global';
 | 
			
		||||
 | 
			
		||||
import Form from './../../plugins/form';
 | 
			
		||||
import Error from './../../plugins/error';
 | 
			
		||||
import BulkAction from './../../plugins/bulk-action';
 | 
			
		||||
 | 
			
		||||
// plugin setup
 | 
			
		||||
Vue.use(DashboardPlugin);
 | 
			
		||||
 | 
			
		||||
const app = new Vue({
 | 
			
		||||
    el: '#app',
 | 
			
		||||
 | 
			
		||||
    mixins: [
 | 
			
		||||
        Global
 | 
			
		||||
    ],
 | 
			
		||||
 | 
			
		||||
    data: function () {
 | 
			
		||||
        return {
 | 
			
		||||
            form: new Form('document'),
 | 
			
		||||
            bulk_action: new BulkAction('documents'),
 | 
			
		||||
            totals: {
 | 
			
		||||
                sub: 0,
 | 
			
		||||
                item_discount: '',
 | 
			
		||||
                discount: '',
 | 
			
		||||
                discount_text: false,
 | 
			
		||||
                taxes: [],
 | 
			
		||||
                total: 0
 | 
			
		||||
            },
 | 
			
		||||
            transaction: [],
 | 
			
		||||
            edit: {
 | 
			
		||||
                status: false,
 | 
			
		||||
                currency: false,
 | 
			
		||||
                items: 0,
 | 
			
		||||
            },
 | 
			
		||||
            colspan: 6,
 | 
			
		||||
            discount: false,
 | 
			
		||||
            tax: false,
 | 
			
		||||
            discounts: [],
 | 
			
		||||
            tax_id: [],
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            items: [],
 | 
			
		||||
            taxes: [],
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    mounted() {
 | 
			
		||||
        if ((document.getElementById('items') != null) && (document.getElementById('items').rows)) {
 | 
			
		||||
            this.colspan = document.getElementById("items").rows[0].cells.length - 1;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        onCalculateTotal() {
 | 
			
		||||
            let global_discount = this.discount;
 | 
			
		||||
            let discount_total = 0;
 | 
			
		||||
            let line_item_discount_total = 0;
 | 
			
		||||
            let taxes = document_taxes;
 | 
			
		||||
            let sub_total = 0;
 | 
			
		||||
            let totals_taxes = [];
 | 
			
		||||
            let grand_total = 0;
 | 
			
		||||
 
 | 
			
		||||
            // items calculate
 | 
			
		||||
            this.items.forEach(function(item) {
 | 
			
		||||
                let discount = 0;
 | 
			
		||||
 | 
			
		||||
                item.total = item.price * item.quantity;
 | 
			
		||||
                item.grand_total = item.price * item.quantity;
 | 
			
		||||
 | 
			
		||||
                // item discount calculate.
 | 
			
		||||
                let line_discount_amount = 0;
 | 
			
		||||
 | 
			
		||||
                if (item.discount) {
 | 
			
		||||
                    line_discount_amount = item.total * (item.discount / 100);
 | 
			
		||||
 | 
			
		||||
                    item_discounted_total = item.total -= line_discount_amount;
 | 
			
		||||
                    discount = item.discount;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let item_discounted_total = item.total;
 | 
			
		||||
 | 
			
		||||
                if (global_discount) {
 | 
			
		||||
                    item_discounted_total = item.total - (item.total * (global_discount / 100));
 | 
			
		||||
 | 
			
		||||
                    discount = global_discount;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // item tax calculate.
 | 
			
		||||
                if (item.tax_ids) {
 | 
			
		||||
                    let inclusives = [];
 | 
			
		||||
                    let compounds = [];
 | 
			
		||||
 | 
			
		||||
                    item.tax_ids.forEach(function(item_tax, item_tax_index) {
 | 
			
		||||
                        for (var index_taxes = 0; index_taxes < taxes.length; index_taxes++) {
 | 
			
		||||
                            let tax = taxes[index_taxes];
 | 
			
		||||
 | 
			
		||||
                            if (item_tax.id != tax.id) {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            switch (tax.type) {
 | 
			
		||||
                                case 'inclusive':
 | 
			
		||||
                                    inclusives.push({
 | 
			
		||||
                                        tax_index: item_tax_index,
 | 
			
		||||
                                        tax_id: tax.id,
 | 
			
		||||
                                        tax_name: tax.title,
 | 
			
		||||
                                        tax_rate: tax.rate
 | 
			
		||||
                                    });
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case 'compound':
 | 
			
		||||
                                    compounds.push({
 | 
			
		||||
                                        tax_index: item_tax_index,
 | 
			
		||||
                                        tax_id: tax.id,
 | 
			
		||||
                                        tax_name: tax.title,
 | 
			
		||||
                                        tax_rate: tax.rate
 | 
			
		||||
                                    });
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case 'fixed':
 | 
			
		||||
                                    item_tax.price = tax.rate * item.quantity;
 | 
			
		||||
 | 
			
		||||
                                    totals_taxes = this.calculateTotalsTax(totals_taxes, tax.id, tax.title, item_tax.price);
 | 
			
		||||
 | 
			
		||||
                                    item.grand_total += item_tax.price;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case 'withholding':
 | 
			
		||||
                                    item_tax.price = 0 - item.total * (tax.rate / 100);
 | 
			
		||||
 | 
			
		||||
                                    totals_taxes = this.calculateTotalsTax(totals_taxes, tax.id, tax.title, item_tax.price);
 | 
			
		||||
 | 
			
		||||
                                    item.grand_total += item_tax.price;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                default:
 | 
			
		||||
                                    item_tax.price = item.total * (tax.rate / 100);
 | 
			
		||||
 | 
			
		||||
                                    totals_taxes = this.calculateTotalsTax(totals_taxes, tax.id, tax.title, item_tax.price);
 | 
			
		||||
 | 
			
		||||
                                    item.grand_total += item_tax.price;
 | 
			
		||||
                                    break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }, this);
 | 
			
		||||
 | 
			
		||||
                    if (inclusives.length) {
 | 
			
		||||
                        let inclusive_total = 0;
 | 
			
		||||
 | 
			
		||||
                        inclusives.forEach(function(inclusive) {
 | 
			
		||||
                            inclusive_total += inclusive.tax_rate;
 | 
			
		||||
 | 
			
		||||
                            // tax price
 | 
			
		||||
                            item.tax_ids[inclusive.tax_index].price = item.grand_total / (1 + inclusive.tax_rate / 100);
 | 
			
		||||
 | 
			
		||||
                            totals_taxes = this.calculateTotalsTax(totals_taxes, inclusive.tax_id, inclusive.tax_name, item.tax_ids[inclusive.tax_index].price);
 | 
			
		||||
                        }, this);
 | 
			
		||||
 | 
			
		||||
                        let item_base_rate = item.grand_total / (1 + inclusive_total / 100);
 | 
			
		||||
 | 
			
		||||
                        item.grand_total = item.grand_total - item_base_rate;
 | 
			
		||||
 | 
			
		||||
                        item.total = item_base_rate + discount;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (compounds.length) {
 | 
			
		||||
                        let price = 0;
 | 
			
		||||
 | 
			
		||||
                        compounds.forEach(function(compound) {
 | 
			
		||||
                            price = (item.grand_total / 100) * compound.tax_rate;
 | 
			
		||||
 | 
			
		||||
                            item.tax_ids[compound.tax_index].price = price;
 | 
			
		||||
 | 
			
		||||
                            totals_taxes = this.calculateTotalsTax(totals_taxes, compound.tax_id, compound.tax_name, price);
 | 
			
		||||
                        }, this);
 | 
			
		||||
 | 
			
		||||
                        item.grand_total += price;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                sub_total += item.total;
 | 
			
		||||
                grand_total += item.grand_total;
 | 
			
		||||
            }, this);
 | 
			
		||||
 | 
			
		||||
            this.totals.sub = sub_total;
 | 
			
		||||
            this.totals.taxes = totals_taxes;
 | 
			
		||||
            this.totals.total = grand_total;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onCalculateTotal2() {
 | 
			
		||||
            let sub_total = 0;
 | 
			
		||||
            let discount_total = 0;
 | 
			
		||||
            let line_item_discount_total = 0;
 | 
			
		||||
            let tax_total = 0;
 | 
			
		||||
            let grand_total = 0;
 | 
			
		||||
            let items = this.items;
 | 
			
		||||
            let discount_in_totals = this.discount;
 | 
			
		||||
 | 
			
		||||
            if (items.length) {
 | 
			
		||||
                let index = 0;
 | 
			
		||||
 | 
			
		||||
                // get all items.
 | 
			
		||||
                for (index = 0; index < items.length; index++) {
 | 
			
		||||
                    let discount = 0;
 | 
			
		||||
                    // get row item and set item variable.
 | 
			
		||||
                    let item = items[index];
 | 
			
		||||
 | 
			
		||||
                    // item sub total calcute.
 | 
			
		||||
                    let item_total = item.price * item.quantity;
 | 
			
		||||
 | 
			
		||||
                    // item discount calculate.
 | 
			
		||||
                    let line_discount_amount = 0;
 | 
			
		||||
 | 
			
		||||
                    if (item.discount) {
 | 
			
		||||
                        line_discount_amount = item_total * (item.discount / 100);
 | 
			
		||||
 | 
			
		||||
                        item_discounted_total = item_total -= line_discount_amount;
 | 
			
		||||
                        discount = item.discount;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    let item_discounted_total = item_total;
 | 
			
		||||
 | 
			
		||||
                    if (discount_in_totals) {
 | 
			
		||||
                        item_discounted_total = item_total - (item_total * (discount_in_totals / 100));
 | 
			
		||||
                        discount = discount_in_totals;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // item tax calculate.
 | 
			
		||||
                    let item_tax_total = 0;
 | 
			
		||||
 | 
			
		||||
                    if (item.tax_ids) {
 | 
			
		||||
                        let inclusives = [];
 | 
			
		||||
                        let compounds = [];
 | 
			
		||||
                        let index_taxes = 0;
 | 
			
		||||
                        let taxes = document_taxes;
 | 
			
		||||
 | 
			
		||||
                        item.tax_ids.forEach(function(item_tax, item_tax_index) {
 | 
			
		||||
                            for (index_taxes = 0; index_taxes < taxes.length; index_taxes++) {
 | 
			
		||||
                                let tax = taxes[index_taxes];
 | 
			
		||||
 | 
			
		||||
                                if (item_tax.id != tax.id) {
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                switch (tax.type) {
 | 
			
		||||
                                    case 'inclusive':
 | 
			
		||||
                                        inclusives.push(tax);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 'compound':
 | 
			
		||||
                                        compounds.push(tax);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 'fixed':
 | 
			
		||||
                                        item_tax_total = tax.rate * item.quantity;
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    case 'withholding':
 | 
			
		||||
                                        item_tax_total = 0 - item.price * item.quantity * (tax.rate / 100);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    default:
 | 
			
		||||
                                        item_tax_total = item.price * item.quantity * (tax.rate / 100);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                this.items[index].tax_ids[item_tax_index].price = item_tax_total;
 | 
			
		||||
                            }
 | 
			
		||||
                        }, this);
 | 
			
		||||
 | 
			
		||||
                        if (inclusives.length) {
 | 
			
		||||
                            let item_sub_and_tax_total = item_discounted_total + item_tax_total;
 | 
			
		||||
 | 
			
		||||
                            let inclusive_total = 0;
 | 
			
		||||
 | 
			
		||||
                            inclusives.forEach(function(inclusive) {
 | 
			
		||||
                                inclusive_total += inclusive.rate;
 | 
			
		||||
                            });
 | 
			
		||||
 | 
			
		||||
                            let item_base_rate = item_sub_and_tax_total / (1 + inclusive_total / 100);
 | 
			
		||||
 | 
			
		||||
                            item_tax_total = item_sub_and_tax_total - item_base_rate;
 | 
			
		||||
 | 
			
		||||
                            item_total = item_base_rate + discount;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (compounds.length) {
 | 
			
		||||
                            compounds.forEach(function(compound) {
 | 
			
		||||
                                item_tax_total += ((item_discounted_total + item_tax_total) / 100) * compound.rate;
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // set item total
 | 
			
		||||
                    if (item.discount) {
 | 
			
		||||
                        items[index].total = item_discounted_total;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        items[index].total = item_total;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // calculate sub, tax, discount all items.
 | 
			
		||||
                    line_item_discount_total += line_discount_amount;
 | 
			
		||||
                    sub_total += item_total;
 | 
			
		||||
                    tax_total += item_tax_total;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // set global total variable.
 | 
			
		||||
            this.totals.sub = sub_total;
 | 
			
		||||
            //this.totals.taxes = Math.abs(tax_total);
 | 
			
		||||
            this.totals.item_discount = line_item_discount_total;
 | 
			
		||||
 | 
			
		||||
            // Apply discount to total
 | 
			
		||||
            if (discount_in_totals) {
 | 
			
		||||
                discount_total = sub_total * (discount_in_totals / 100);
 | 
			
		||||
 | 
			
		||||
                this.totals.discount = discount_total;
 | 
			
		||||
 | 
			
		||||
                sub_total = sub_total - (sub_total * (discount_in_totals / 100));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // set all item grand total.
 | 
			
		||||
            grand_total = sub_total + tax_total;
 | 
			
		||||
 | 
			
		||||
            this.totals.total = grand_total;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onCalculateTaxes() {
 | 
			
		||||
            let taxes = document_taxes;
 | 
			
		||||
 | 
			
		||||
            this.items.forEach(function (item, index) {
 | 
			
		||||
                let inclusives = [];
 | 
			
		||||
                let compounds = [];
 | 
			
		||||
                let index_taxes = 0;
 | 
			
		||||
    
 | 
			
		||||
                item.tax_ids.forEach(function(item_tax, item_tax_index) {
 | 
			
		||||
                    item_tax_total = 0;
 | 
			
		||||
 | 
			
		||||
                    for (index_taxes = 0; index_taxes < taxes.length; index_taxes++) {
 | 
			
		||||
                        let tax = taxes[index_taxes];
 | 
			
		||||
    
 | 
			
		||||
                        if (item_tax.id != tax.id) {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
    
 | 
			
		||||
                        switch (tax.type) {
 | 
			
		||||
                            case 'inclusive':
 | 
			
		||||
                                inclusives.push(tax);
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 'compound':
 | 
			
		||||
                                compounds.push(tax);
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 'fixed':
 | 
			
		||||
                                item_tax_total += tax.rate * item.quantity;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 'withholding':
 | 
			
		||||
                                item_tax_total += 0 - item.price * (tax.rate / 100);
 | 
			
		||||
                                break;
 | 
			
		||||
                            default:
 | 
			
		||||
                                item_tax_total += item.price * (tax.rate / 100);
 | 
			
		||||
                                break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    this.items[index].tax_ids[item_tax_index].price = item_tax_total;
 | 
			
		||||
                }, this);
 | 
			
		||||
    
 | 
			
		||||
                if (inclusives.length) {
 | 
			
		||||
                    let item_sub_and_tax_total = item_discounted_total + item_tax_total;
 | 
			
		||||
    
 | 
			
		||||
                    let inclusive_total = 0;
 | 
			
		||||
    
 | 
			
		||||
                    inclusives.forEach(function(inclusive) {
 | 
			
		||||
                        inclusive_total += inclusive.rate;
 | 
			
		||||
                    }, this);
 | 
			
		||||
    
 | 
			
		||||
                    let item_base_rate = item_sub_and_tax_total / (1 + inclusive_total / 100);
 | 
			
		||||
    
 | 
			
		||||
                    item_tax_total = item_sub_and_tax_total - item_base_rate;
 | 
			
		||||
    
 | 
			
		||||
                    item_total = item_base_rate + discount;
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                if (compounds.length) {
 | 
			
		||||
                    compounds.forEach(function(compound) {
 | 
			
		||||
                        item_tax_total += ((item_discounted_total + item_tax_total) / 100) * compound.rate;
 | 
			
		||||
                    }, this);
 | 
			
		||||
                }
 | 
			
		||||
            }, this);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        calculateTotalsTax(totals_taxes, id, name, price) {
 | 
			
		||||
            let total_tax_index = totals_taxes.findIndex(total_tax => {
 | 
			
		||||
                if (total_tax.id === id) {
 | 
			
		||||
                  return true;
 | 
			
		||||
                }
 | 
			
		||||
            }, this);
 | 
			
		||||
 | 
			
		||||
            if (total_tax_index === -1) {
 | 
			
		||||
                totals_taxes.push({
 | 
			
		||||
                    id: id,
 | 
			
		||||
                    name: name,
 | 
			
		||||
                    total: price,
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                totals_taxes[total_tax_index].total = parseFloat(totals_taxes[total_tax_index].total) + parseFloat(price);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return totals_taxes;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        getItemByTaxes(item) {
 | 
			
		||||
            let item_tax_ids = [];
 | 
			
		||||
            let taxes = document_taxes;
 | 
			
		||||
 | 
			
		||||
            let inclusives = [];
 | 
			
		||||
            let compounds = [];
 | 
			
		||||
            let index_taxes = 0;
 | 
			
		||||
            let item_tax_total = 0;
 | 
			
		||||
 | 
			
		||||
            item.tax_ids.forEach(function(item_tax, item_tax_index) {
 | 
			
		||||
                item_tax_total = 0;
 | 
			
		||||
 | 
			
		||||
                for (index_taxes = 0; index_taxes < taxes.length; index_taxes++) {
 | 
			
		||||
                    let tax = taxes[index_taxes];
 | 
			
		||||
 | 
			
		||||
                    if (item_tax.id != tax.id) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    switch (tax.type) {
 | 
			
		||||
                        case 'inclusive':
 | 
			
		||||
                            inclusives.push(tax);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'compound':
 | 
			
		||||
                            compounds.push(tax);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'fixed':
 | 
			
		||||
                            item_tax_total += tax.rate * item.quantity;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case 'withholding':
 | 
			
		||||
                            item_tax_total += 0 - item.price * (tax.rate / 100);
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            item_tax_total += item.price * (tax.rate / 100);
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                item_tax_ids.push({
 | 
			
		||||
                    id: item_tax.id,
 | 
			
		||||
                    price: item_tax_total 
 | 
			
		||||
                });
 | 
			
		||||
            }, this);
 | 
			
		||||
 | 
			
		||||
            if (inclusives.length) {
 | 
			
		||||
                let item_sub_and_tax_total = item_discounted_total + item_tax_total;
 | 
			
		||||
 | 
			
		||||
                let inclusive_total = 0;
 | 
			
		||||
 | 
			
		||||
                inclusives.forEach(function(inclusive) {
 | 
			
		||||
                    inclusive_total += inclusive.rate;
 | 
			
		||||
                }, this);
 | 
			
		||||
 | 
			
		||||
                let item_base_rate = item_sub_and_tax_total / (1 + inclusive_total / 100);
 | 
			
		||||
 | 
			
		||||
                item_tax_total = item_sub_and_tax_total - item_base_rate;
 | 
			
		||||
 | 
			
		||||
                item_total = item_base_rate + discount;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (compounds.length) {
 | 
			
		||||
                compounds.forEach(function(compound) {
 | 
			
		||||
                    item_tax_total += ((item_discounted_total + item_tax_total) / 100) * compound.rate;
 | 
			
		||||
                }, this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return item_tax_ids;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        // Select Item added form
 | 
			
		||||
        onSelectedItem(item) {
 | 
			
		||||
            let total = 1 * item.price;
 | 
			
		||||
            let item_taxes = [];
 | 
			
		||||
 | 
			
		||||
            if (item.tax_ids) {
 | 
			
		||||
                item.tax_ids.forEach(function (tax_id, index) {
 | 
			
		||||
                    if (this.taxes.includes(tax_id)) {
 | 
			
		||||
                        this.taxes[tax_id].push(item.id);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.taxes.push(tax_id);
 | 
			
		||||
 | 
			
		||||
                        this.taxes[tax_id] = [];
 | 
			
		||||
 | 
			
		||||
                        this.taxes[tax_id].push(item.id);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    item_taxes.push({
 | 
			
		||||
                        id: tax_id,
 | 
			
		||||
                        price: 10,
 | 
			
		||||
                    });
 | 
			
		||||
                }, this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.form.items.push({
 | 
			
		||||
                item_id: item.id,
 | 
			
		||||
                name: item.name,
 | 
			
		||||
                description: item.description,
 | 
			
		||||
                quantity: 1,
 | 
			
		||||
                price: item.price,
 | 
			
		||||
                tax_ids: item.tax_ids,
 | 
			
		||||
                discount: 0,
 | 
			
		||||
                total: total,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this.items.push({
 | 
			
		||||
                item_id: item.id,
 | 
			
		||||
                name: item.name,
 | 
			
		||||
                description: item.description,
 | 
			
		||||
                quantity: 1,
 | 
			
		||||
                price: item.price,
 | 
			
		||||
                add_tax: (item_taxes.length) ? true : false,
 | 
			
		||||
                tax_ids: item_taxes,
 | 
			
		||||
                add_discount: false,
 | 
			
		||||
                discount: 0,
 | 
			
		||||
                total: total,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this.onCalculateTotal();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onSelectedTax(item_index) {
 | 
			
		||||
            if (!this.tax_id) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let selected_tax;
 | 
			
		||||
 | 
			
		||||
            document_taxes.forEach(function(tax) {
 | 
			
		||||
                if (tax.id == this.tax_id) {
 | 
			
		||||
                    selected_tax = tax;
 | 
			
		||||
                }
 | 
			
		||||
            }, this);
 | 
			
		||||
 | 
			
		||||
            this.items[item_index].tax_ids.push({
 | 
			
		||||
                id: selected_tax.id,
 | 
			
		||||
                name: selected_tax.title,
 | 
			
		||||
                price: 0
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            this.form.items[item_index].tax_ids.push(this.tax_id);
 | 
			
		||||
 | 
			
		||||
            if (this.taxes.includes(this.tax_id)) {
 | 
			
		||||
                this.taxes[this.tax_id].push(this.items[item_index].item_id);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.taxes[this.tax_id] = [];
 | 
			
		||||
 | 
			
		||||
                this.taxes[this.tax_id].push(this.items[item_index].item_id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.tax_id = '';
 | 
			
		||||
 | 
			
		||||
            this.onCalculateTotal();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        // remove document item row => row_id = index
 | 
			
		||||
        onDeleteItem(index) {
 | 
			
		||||
            this.items.splice(index, 1);
 | 
			
		||||
            this.form.items.splice(index, 1);
 | 
			
		||||
 | 
			
		||||
            this.onCalculateTotal();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onAddDiscount(item_index) {
 | 
			
		||||
            this.items[item_index].add_discount = true;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onDeleteDiscount(item_index) {
 | 
			
		||||
            this.items[item_index].add_discount = false;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onAddTax(item_index) {
 | 
			
		||||
            this.items[item_index].add_tax = true;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onDeleteTax(item_index, tax_index) {
 | 
			
		||||
            this.items[item_index].tax_ids.splice(tax_index, 1);
 | 
			
		||||
            this.form.items[item_index].tax_ids.splice(tax_index, 1);
 | 
			
		||||
 | 
			
		||||
            if (!this.items[item_index].tax_ids.length) {
 | 
			
		||||
                this.items[item_index].add_tax = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.onCalculateTotal();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        async onPayment() {
 | 
			
		||||
            let document_id = document.getElementById('document_id').value;
 | 
			
		||||
 | 
			
		||||
            let payment = {
 | 
			
		||||
                modal: false,
 | 
			
		||||
                url: url + '/modals/documents/' + document_id + '/transactions/create',
 | 
			
		||||
                title: '',
 | 
			
		||||
                html: '',
 | 
			
		||||
                buttons:{}
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let payment_promise = Promise.resolve(window.axios.get(payment.url));
 | 
			
		||||
 | 
			
		||||
            payment_promise.then(response => {
 | 
			
		||||
                payment.modal = true;
 | 
			
		||||
                payment.title = response.data.data.title;
 | 
			
		||||
                payment.html = response.data.html;
 | 
			
		||||
                payment.buttons = response.data.data.buttons;
 | 
			
		||||
 | 
			
		||||
                this.component = Vue.component('add-new-component', (resolve, reject) => {
 | 
			
		||||
                    resolve({
 | 
			
		||||
                        template: '<div id="dynamic-payment-component"><akaunting-modal-add-new modal-dialog-class="modal-md" :show="payment.modal" @submit="onSubmit" @cancel="onCancel" :buttons="payment.buttons" :title="payment.title" :is_component=true :message="payment.html"></akaunting-modal-add-new></div>',
 | 
			
		||||
 | 
			
		||||
                        mixins: [
 | 
			
		||||
                            Global
 | 
			
		||||
                        ],
 | 
			
		||||
 | 
			
		||||
                        data: function () {
 | 
			
		||||
                            return {
 | 
			
		||||
                                form:{},
 | 
			
		||||
                                payment: payment,
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
 | 
			
		||||
                        methods: {
 | 
			
		||||
                            onSubmit(event) {
 | 
			
		||||
                                this.form = event;
 | 
			
		||||
                                this.form.response = {};
 | 
			
		||||
 | 
			
		||||
                                this.loading = true;
 | 
			
		||||
 | 
			
		||||
                                let data = this.form.data();
 | 
			
		||||
 | 
			
		||||
                                FormData.prototype.appendRecursive = function(data, wrapper = null) {
 | 
			
		||||
                                    for(var name in data) {
 | 
			
		||||
                                        if (wrapper) {
 | 
			
		||||
                                            if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                                                this.appendRecursive(data[name], wrapper + '[' + name + ']');
 | 
			
		||||
                                            } else {
 | 
			
		||||
                                                this.append(wrapper + '[' + name + ']', data[name]);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } else {
 | 
			
		||||
                                            if ((typeof data[name] == 'object' || data[name].constructor === Array) && ((data[name] instanceof File != true ) && (data[name] instanceof Blob != true))) {
 | 
			
		||||
                                                this.appendRecursive(data[name], name);
 | 
			
		||||
                                            } else {
 | 
			
		||||
                                                this.append(name, data[name]);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                };
 | 
			
		||||
 | 
			
		||||
                                let form_data = new FormData();
 | 
			
		||||
                                form_data.appendRecursive(data);
 | 
			
		||||
 | 
			
		||||
                                window.axios({
 | 
			
		||||
                                    method: this.form.method,
 | 
			
		||||
                                    url: this.form.action,
 | 
			
		||||
                                    data: form_data,
 | 
			
		||||
                                    headers: {
 | 
			
		||||
                                        'X-CSRF-TOKEN': window.Laravel.csrfToken,
 | 
			
		||||
                                        'X-Requested-With': 'XMLHttpRequest',
 | 
			
		||||
                                        'Content-Type': 'multipart/form-data'
 | 
			
		||||
                                    }
 | 
			
		||||
                                })
 | 
			
		||||
                                .then(response => {
 | 
			
		||||
                                    if (response.data.success) {
 | 
			
		||||
                                        if (response.data.redirect) {
 | 
			
		||||
                                            this.form.loading = true;
 | 
			
		||||
 | 
			
		||||
                                            window.location.href = response.data.redirect;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    if (response.data.error) {
 | 
			
		||||
                                        this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                                        this.form.response = response.data;
 | 
			
		||||
                                    }
 | 
			
		||||
                                })
 | 
			
		||||
                                .catch(error => {
 | 
			
		||||
                                    this.form.loading = false;
 | 
			
		||||
 | 
			
		||||
                                    this.form.onFail(error);
 | 
			
		||||
 | 
			
		||||
                                    this.method_show_html = error.message;
 | 
			
		||||
                                });
 | 
			
		||||
                            },
 | 
			
		||||
 | 
			
		||||
                            onCancel() {
 | 
			
		||||
                                this.payment.modal = false;
 | 
			
		||||
                                this.payment.html = null;
 | 
			
		||||
 | 
			
		||||
                                let documentClasses = document.body.classList;
 | 
			
		||||
 | 
			
		||||
                                documentClasses.remove("modal-open");
 | 
			
		||||
                            },
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
                });
 | 
			
		||||
            })
 | 
			
		||||
            .catch(error => {
 | 
			
		||||
            })
 | 
			
		||||
            .finally(function () {
 | 
			
		||||
                // always executed
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    created() {
 | 
			
		||||
        this.form.items = [];
 | 
			
		||||
 | 
			
		||||
        if (typeof document_items !== 'undefined' && document_items) {
 | 
			
		||||
            this.edit.status = true;
 | 
			
		||||
            document_items.forEach(function(item) {
 | 
			
		||||
                // form set item
 | 
			
		||||
                this.form.items.push({
 | 
			
		||||
                    item_id: item.item_id,
 | 
			
		||||
                    name: item.name,
 | 
			
		||||
                    description: item.description,
 | 
			
		||||
                    quantity: item.quantity,
 | 
			
		||||
                    price: (item.price).toFixed(2),
 | 
			
		||||
                    tax_ids: item.tax_ids,
 | 
			
		||||
                    discount: item.discount_rate,
 | 
			
		||||
                    total: (item.total).toFixed(2)
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                if (item.tax_ids) {
 | 
			
		||||
                    item.tax_ids.forEach(function (tax_id, index) {
 | 
			
		||||
                        if (this.taxes.includes(tax_id)) {
 | 
			
		||||
                            this.taxes[tax_id].push(item.id);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.taxes.push(tax_id);
 | 
			
		||||
    
 | 
			
		||||
                            this.taxes[tax_id] = [];
 | 
			
		||||
    
 | 
			
		||||
                            this.taxes[tax_id].push(item.id);
 | 
			
		||||
                        }
 | 
			
		||||
                    }, this);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let item_taxes = [];
 | 
			
		||||
 | 
			
		||||
                item.taxes.forEach(function(item_tax) {
 | 
			
		||||
                    item_taxes.push({
 | 
			
		||||
                        id: item_tax.tax_id,
 | 
			
		||||
                        name: item_tax.name,
 | 
			
		||||
                        price: (item_tax.amount).toFixed(2),
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                this.items.push({
 | 
			
		||||
                    item_id: item.item_id,
 | 
			
		||||
                    name: item.name,
 | 
			
		||||
                    description: item.description,
 | 
			
		||||
                    quantity: item.quantity,
 | 
			
		||||
                    price: (item.price).toFixed(2),
 | 
			
		||||
                    add_tax: (item_taxes.length) ? true : false,
 | 
			
		||||
                    tax_ids: item_taxes,
 | 
			
		||||
                    add_discount: (item_taxes.length) ? true : false,
 | 
			
		||||
                    discount: item.discount_rate,
 | 
			
		||||
                    total: (item.total).toFixed(2)
 | 
			
		||||
                });
 | 
			
		||||
            }, this);
 | 
			
		||||
 | 
			
		||||
            this.items.forEach(function(item) {
 | 
			
		||||
                item.tax_ids.forEach(function(tax) {
 | 
			
		||||
                    let total_tax_index = this.totals.taxes.findIndex(total_tax => {
 | 
			
		||||
                        if (total_tax.id === tax.id) {
 | 
			
		||||
                          return true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }, this);
 | 
			
		||||
 | 
			
		||||
                    if (total_tax_index === -1) {
 | 
			
		||||
                        this.totals.taxes.push({
 | 
			
		||||
                            id: tax.id,
 | 
			
		||||
                            name: tax.name,
 | 
			
		||||
                            total: tax.price,
 | 
			
		||||
                        });
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.totals.taxes[total_tax_index].total = parseFloat(this.totals.taxes[total_tax_index].total) + parseFloat(tax.price);
 | 
			
		||||
                    }
 | 
			
		||||
                }, this);
 | 
			
		||||
            }, this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										22
									
								
								resources/assets/js/views/portal/invoices.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								resources/assets/js/views/portal/invoices.js
									
									
									
									
										vendored
									
									
								
							@@ -54,11 +54,20 @@ const app = new Vue({
 | 
			
		||||
 | 
			
		||||
            let method = payment_method.split('.');
 | 
			
		||||
 | 
			
		||||
            let path = url + '/portal/invoices/' + this.form.invoice_id + '/' + method[0];
 | 
			
		||||
            let path = url + '/portal/invoices/' + this.form.document_id + '/' + method[0];
 | 
			
		||||
 | 
			
		||||
            //this.method_show_html = '<div id="loading" class="text-center"><i class="fa fa-spinner fa-spin fa-5x checkout-spin"></i></div>';
 | 
			
		||||
            this.method_show_html = Vue.component('payment-method-confirm', function (resolve, reject) {
 | 
			
		||||
                resolve({
 | 
			
		||||
                    template:'<div id="loading" class="description text-center"><i class="fa fa-spinner fa-spin fa-5x checkout-spin"></i></div>'
 | 
			
		||||
                    
 | 
			
		||||
                })
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            axios.get(path)
 | 
			
		||||
            axios.get(path, {
 | 
			
		||||
                params: {
 | 
			
		||||
                    payment_method: payment_method
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.method_show_html = '';
 | 
			
		||||
 | 
			
		||||
@@ -130,6 +139,13 @@ const app = new Vue({
 | 
			
		||||
 | 
			
		||||
            let payment_action = payment_action_path[payment_method];
 | 
			
		||||
 | 
			
		||||
            this.method_show_html = Vue.component('payment-method-confirm', function (resolve, reject) {
 | 
			
		||||
                resolve({
 | 
			
		||||
                    template:'<div id="loading" class="description text-center"><i class="fa fa-spinner fa-spin fa-5x checkout-spin"></i></div>'
 | 
			
		||||
                    
 | 
			
		||||
                })
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            axios.get(payment_action)
 | 
			
		||||
            .then(response => {
 | 
			
		||||
                this.method_show_html = '';
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user